diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0ae8a4f9b..a7791dc7e 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -574,6 +574,8 @@ set(NP_LIBS src/core/libraries/np_common/np_common.cpp
src/core/libraries/np_web_api/np_web_api.h
src/core/libraries/np_party/np_party.cpp
src/core/libraries/np_party/np_party.h
+ src/core/libraries/np_auth/np_auth.cpp
+ src/core/libraries/np_auth/np_auth.h
)
set(ZLIB_LIB src/core/libraries/zlib/zlib.cpp
diff --git a/README.md b/README.md
index 0e2248970..985bba586 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
-
+
@@ -146,16 +146,13 @@ The following firmware modules are supported and must be placed in shadPS4's `us
# Main team
- [**georgemoralis**](https://github.com/georgemoralis)
-- [**raphaelthegreat**](https://github.com/raphaelthegreat)
- [**psucien**](https://github.com/psucien)
-- [**skmp**](https://github.com/skmp)
-- [**wheremyfoodat**](https://github.com/wheremyfoodat)
-- [**raziel1000**](https://github.com/raziel1000)
- [**viniciuslrangel**](https://github.com/viniciuslrangel)
- [**roamic**](https://github.com/vladmikhalin)
-- [**poly**](https://github.com/polybiusproxy)
- [**squidbus**](https://github.com/squidbus)
- [**frodo**](https://github.com/baggins183)
+- [**Stephen Miller**](https://github.com/StevenMiller123)
+- [**kalaposfos13**](https://github.com/kalaposfos13)
Logo is done by [**Xphalnos**](https://github.com/Xphalnos)
@@ -166,11 +163,11 @@ Open a PR and we'll check it :)
# Translations
-If you want to translate shadPS4 to your language we use [**crowdin**](https://crowdin.com/project/shadps4-emulator).
+If you want to translate shadPS4 to your language we use [**Crowdin**](https://crowdin.com/project/shadps4-emulator).
# Contributors
-
+
diff --git a/src/common/logging/filter.cpp b/src/common/logging/filter.cpp
index bed7802ed..867d62916 100644
--- a/src/common/logging/filter.cpp
+++ b/src/common/logging/filter.cpp
@@ -101,6 +101,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
SUB(Lib, Ssl2) \
SUB(Lib, SysModule) \
SUB(Lib, Move) \
+ SUB(Lib, NpAuth) \
SUB(Lib, NpCommon) \
SUB(Lib, NpManager) \
SUB(Lib, NpScore) \
diff --git a/src/common/logging/types.h b/src/common/logging/types.h
index c07efbc0d..e5714a81a 100644
--- a/src/common/logging/types.h
+++ b/src/common/logging/types.h
@@ -69,6 +69,7 @@ enum class Class : u8 {
Lib_Http2, ///< The LibSceHttp2 implementation.
Lib_SysModule, ///< The LibSceSysModule implementation
Lib_NpCommon, ///< The LibSceNpCommon implementation
+ Lib_NpAuth, ///< The LibSceNpAuth implementation
Lib_NpManager, ///< The LibSceNpManager implementation
Lib_NpScore, ///< The LibSceNpScore implementation
Lib_NpTrophy, ///< The LibSceNpTrophy implementation
diff --git a/src/core/libraries/gnmdriver/gnmdriver.cpp b/src/core/libraries/gnmdriver/gnmdriver.cpp
index e8560b2b8..25ac4921c 100644
--- a/src/core/libraries/gnmdriver/gnmdriver.cpp
+++ b/src/core/libraries/gnmdriver/gnmdriver.cpp
@@ -2804,7 +2804,7 @@ void RegisterlibSceGnmDriver(Core::Loader::SymbolsResolver* sym) {
liverpool = std::make_unique();
presenter = std::make_unique(*g_window, liverpool.get());
- const int result = sceKernelGetCompiledSdkVersion(&sdk_version);
+ const s32 result = sceKernelGetCompiledSdkVersion(&sdk_version);
if (result != ORBIS_OK) {
sdk_version = 0;
}
diff --git a/src/core/libraries/kernel/memory.cpp b/src/core/libraries/kernel/memory.cpp
index cbc5ad77e..8a0c91479 100644
--- a/src/core/libraries/kernel/memory.cpp
+++ b/src/core/libraries/kernel/memory.cpp
@@ -106,12 +106,6 @@ s32 PS4_SYSV_ABI sceKernelAvailableDirectMemorySize(u64 searchStart, u64 searchE
if (physAddrOut == nullptr || sizeOut == nullptr) {
return ORBIS_KERNEL_ERROR_EINVAL;
}
- if (searchEnd > sceKernelGetDirectMemorySize()) {
- return ORBIS_KERNEL_ERROR_EINVAL;
- }
- if (searchEnd <= searchStart) {
- return ORBIS_KERNEL_ERROR_ENOMEM;
- }
auto* memory = Core::Memory::Instance();
diff --git a/src/core/libraries/libs.cpp b/src/core/libraries/libs.cpp
index d0f82556e..3f5baf640 100644
--- a/src/core/libraries/libs.cpp
+++ b/src/core/libraries/libs.cpp
@@ -27,6 +27,7 @@
#include "core/libraries/network/netctl.h"
#include "core/libraries/network/ssl.h"
#include "core/libraries/network/ssl2.h"
+#include "core/libraries/np_auth/np_auth.h"
#include "core/libraries/np_common/np_common.h"
#include "core/libraries/np_manager/np_manager.h"
#include "core/libraries/np_party/np_party.h"
@@ -88,6 +89,7 @@ void InitHLELibs(Core::Loader::SymbolsResolver* sym) {
Libraries::NpScore::RegisterlibSceNpScore(sym);
Libraries::NpTrophy::RegisterlibSceNpTrophy(sym);
Libraries::NpWebApi::RegisterlibSceNpWebApi(sym);
+ Libraries::NpAuth::RegisterlibSceNpAuth(sym);
Libraries::ScreenShot::RegisterlibSceScreenShot(sym);
Libraries::AppContent::RegisterlibSceAppContent(sym);
Libraries::PngDec::RegisterlibScePngDec(sym);
diff --git a/src/core/libraries/np_auth/np_auth.cpp b/src/core/libraries/np_auth/np_auth.cpp
new file mode 100644
index 000000000..9ec986f3c
--- /dev/null
+++ b/src/core/libraries/np_auth/np_auth.cpp
@@ -0,0 +1,99 @@
+// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "common/logging/log.h"
+#include "core/libraries/error_codes.h"
+#include "core/libraries/libs.h"
+#include "core/libraries/np_auth/np_auth.h"
+
+namespace Libraries::NpAuth {
+
+s32 PS4_SYSV_ABI sceNpAuthGetAuthorizationCode() {
+ LOG_ERROR(Lib_NpAuth, "(STUBBED) called");
+ return ORBIS_OK;
+}
+
+s32 PS4_SYSV_ABI sceNpAuthGetIdToken() {
+ LOG_ERROR(Lib_NpAuth, "(STUBBED) called");
+ return ORBIS_OK;
+}
+
+s32 PS4_SYSV_ABI sceNpAuthAbortRequest() {
+ LOG_ERROR(Lib_NpAuth, "(STUBBED) called");
+ return ORBIS_OK;
+}
+
+s32 PS4_SYSV_ABI sceNpAuthCreateAsyncRequest() {
+ LOG_ERROR(Lib_NpAuth, "(STUBBED) called");
+ return ORBIS_OK;
+}
+
+s32 PS4_SYSV_ABI sceNpAuthCreateRequest() {
+ LOG_WARNING(Lib_NpAuth, "(DUMMY) called");
+ return 1;
+}
+
+s32 PS4_SYSV_ABI sceNpAuthDeleteRequest(s32 id) {
+ LOG_WARNING(Lib_NpAuth, "(DUMMY) called");
+ return ORBIS_OK;
+}
+
+s32 PS4_SYSV_ABI sceNpAuthGetAuthorizationCodeA() {
+ LOG_ERROR(Lib_NpAuth, "(STUBBED) called");
+ return ORBIS_OK;
+}
+
+s32 PS4_SYSV_ABI sceNpAuthGetAuthorizationCodeV3() {
+ LOG_ERROR(Lib_NpAuth, "(STUBBED) called");
+ return ORBIS_OK;
+}
+
+s32 PS4_SYSV_ABI sceNpAuthGetIdTokenA() {
+ LOG_ERROR(Lib_NpAuth, "(STUBBED) called");
+ return ORBIS_OK;
+}
+
+s32 PS4_SYSV_ABI sceNpAuthGetIdTokenV3() {
+ LOG_ERROR(Lib_NpAuth, "(STUBBED) called");
+ return ORBIS_OK;
+}
+
+s32 PS4_SYSV_ABI sceNpAuthPollAsync() {
+ LOG_ERROR(Lib_NpAuth, "(STUBBED) called");
+ return ORBIS_OK;
+}
+
+s32 PS4_SYSV_ABI sceNpAuthSetTimeout() {
+ LOG_ERROR(Lib_NpAuth, "(STUBBED) called");
+ return ORBIS_OK;
+}
+
+s32 PS4_SYSV_ABI sceNpAuthWaitAsync() {
+ LOG_ERROR(Lib_NpAuth, "(STUBBED) called");
+ return ORBIS_OK;
+}
+
+void RegisterlibSceNpAuth(Core::Loader::SymbolsResolver* sym) {
+ LIB_FUNCTION("KxGkOrQJTqY", "libSceNpAuthCompat", 1, "libSceNpAuth", 1, 1,
+ sceNpAuthGetAuthorizationCode);
+ LIB_FUNCTION("uaB-LoJqHis", "libSceNpAuthCompat", 1, "libSceNpAuth", 1, 1, sceNpAuthGetIdToken);
+ LIB_FUNCTION("cE7wIsqXdZ8", "libSceNpAuth", 1, "libSceNpAuth", 1, 1, sceNpAuthAbortRequest);
+ LIB_FUNCTION("N+mr7GjTvr8", "libSceNpAuth", 1, "libSceNpAuth", 1, 1,
+ sceNpAuthCreateAsyncRequest);
+ LIB_FUNCTION("6bwFkosYRQg", "libSceNpAuth", 1, "libSceNpAuth", 1, 1, sceNpAuthCreateRequest);
+ LIB_FUNCTION("H8wG9Bk-nPc", "libSceNpAuth", 1, "libSceNpAuth", 1, 1, sceNpAuthDeleteRequest);
+ LIB_FUNCTION("KxGkOrQJTqY", "libSceNpAuth", 1, "libSceNpAuth", 1, 1,
+ sceNpAuthGetAuthorizationCode);
+ LIB_FUNCTION("qAUXQ9GdWp8", "libSceNpAuth", 1, "libSceNpAuth", 1, 1,
+ sceNpAuthGetAuthorizationCodeA);
+ LIB_FUNCTION("KI4dHLlTNl0", "libSceNpAuth", 1, "libSceNpAuth", 1, 1,
+ sceNpAuthGetAuthorizationCodeV3);
+ LIB_FUNCTION("uaB-LoJqHis", "libSceNpAuth", 1, "libSceNpAuth", 1, 1, sceNpAuthGetIdToken);
+ LIB_FUNCTION("CocbHVIKPE8", "libSceNpAuth", 1, "libSceNpAuth", 1, 1, sceNpAuthGetIdTokenA);
+ LIB_FUNCTION("RdsFVsgSpZY", "libSceNpAuth", 1, "libSceNpAuth", 1, 1, sceNpAuthGetIdTokenV3);
+ LIB_FUNCTION("gjSyfzSsDcE", "libSceNpAuth", 1, "libSceNpAuth", 1, 1, sceNpAuthPollAsync);
+ LIB_FUNCTION("PM3IZCw-7m0", "libSceNpAuth", 1, "libSceNpAuth", 1, 1, sceNpAuthSetTimeout);
+ LIB_FUNCTION("SK-S7daqJSE", "libSceNpAuth", 1, "libSceNpAuth", 1, 1, sceNpAuthWaitAsync);
+};
+
+} // namespace Libraries::NpAuth
\ No newline at end of file
diff --git a/src/core/libraries/np_auth/np_auth.h b/src/core/libraries/np_auth/np_auth.h
new file mode 100644
index 000000000..a6a66b452
--- /dev/null
+++ b/src/core/libraries/np_auth/np_auth.h
@@ -0,0 +1,29 @@
+// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "common/types.h"
+
+namespace Core::Loader {
+class SymbolsResolver;
+}
+
+namespace Libraries::NpAuth {
+
+s32 PS4_SYSV_ABI sceNpAuthGetAuthorizationCode();
+s32 PS4_SYSV_ABI sceNpAuthGetIdToken();
+s32 PS4_SYSV_ABI sceNpAuthAbortRequest();
+s32 PS4_SYSV_ABI sceNpAuthCreateAsyncRequest();
+s32 PS4_SYSV_ABI sceNpAuthCreateRequest();
+s32 PS4_SYSV_ABI sceNpAuthDeleteRequest(s32 id);
+s32 PS4_SYSV_ABI sceNpAuthGetAuthorizationCodeA();
+s32 PS4_SYSV_ABI sceNpAuthGetAuthorizationCodeV3();
+s32 PS4_SYSV_ABI sceNpAuthGetIdTokenA();
+s32 PS4_SYSV_ABI sceNpAuthGetIdTokenV3();
+s32 PS4_SYSV_ABI sceNpAuthPollAsync();
+s32 PS4_SYSV_ABI sceNpAuthSetTimeout();
+s32 PS4_SYSV_ABI sceNpAuthWaitAsync();
+
+void RegisterlibSceNpAuth(Core::Loader::SymbolsResolver* sym);
+} // namespace Libraries::NpAuth
\ No newline at end of file
diff --git a/src/core/linker.cpp b/src/core/linker.cpp
index 4ccb9d943..69deb464f 100644
--- a/src/core/linker.cpp
+++ b/src/core/linker.cpp
@@ -108,10 +108,22 @@ void Linker::Execute(const std::vector args) {
static constexpr s64 InternalMemorySize = 0x1000000;
void* addr_out{reinterpret_cast(KernelAllocBase)};
- const s32 ret = Libraries::Kernel::sceKernelMapNamedFlexibleMemory(
- &addr_out, InternalMemorySize, 3, 0, "SceKernelInternalMemory");
+ s32 ret = Libraries::Kernel::sceKernelMapNamedFlexibleMemory(&addr_out, InternalMemorySize, 3,
+ 0, "SceKernelInternalMemory");
ASSERT_MSG(ret == 0, "Unable to perform sceKernelInternalMemory mapping");
+ // Simulate libSceGnmDriver initialization, which maps a chunk of direct memory.
+ // Some games fail without accurately emulating this behavior.
+ s64 phys_addr{};
+ ret = Libraries::Kernel::sceKernelAllocateDirectMemory(
+ 0, Libraries::Kernel::sceKernelGetDirectMemorySize(), 0x10000, 0x10000, 3, &phys_addr);
+ if (ret == 0) {
+ void* addr{reinterpret_cast(0xfe0000000)};
+ ret = Libraries::Kernel::sceKernelMapNamedDirectMemory(&addr, 0x10000, 0x13, 0, phys_addr,
+ 0x10000, "SceGnmDriver");
+ }
+ ASSERT_MSG(ret == 0, "Unable to emulate libSceGnmDriver initialization");
+
main_thread.Run([this, module, args](std::stop_token) {
Common::SetCurrentThreadName("GAME_MainThread");
LoadSharedLibraries();
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index f88cede4e..cb80d6be4 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -655,7 +655,7 @@ int MemoryManager::DirectQueryAvailable(PAddr search_start, PAddr search_end, si
if (dmem_area->second.GetEnd() > search_end) {
// We need to trim remaining_size to ignore addresses beyond search_end
- remaining_size = remaining_size > (search_start - dmem_area->second.base)
+ remaining_size = remaining_size > (dmem_area->second.GetEnd() - search_end)
? remaining_size - (dmem_area->second.GetEnd() - search_end)
: 0;
}
diff --git a/src/qt_gui/kbm_gui.cpp b/src/qt_gui/kbm_gui.cpp
index 8777dda95..2e1f6ddce 100644
--- a/src/qt_gui/kbm_gui.cpp
+++ b/src/qt_gui/kbm_gui.cpp
@@ -127,58 +127,9 @@ tr("Do you want to overwrite existing mappings with the mappings from the Common
}
void KBMSettings::ButtonConnects() {
- connect(ui->CrossButton, &QPushButton::clicked, this,
- [this]() { StartTimer(ui->CrossButton); });
- connect(ui->CircleButton, &QPushButton::clicked, this,
- [this]() { StartTimer(ui->CircleButton); });
- connect(ui->TriangleButton, &QPushButton::clicked, this,
- [this]() { StartTimer(ui->TriangleButton); });
- connect(ui->SquareButton, &QPushButton::clicked, this,
- [this]() { StartTimer(ui->SquareButton); });
-
- connect(ui->L1Button, &QPushButton::clicked, this, [this]() { StartTimer(ui->L1Button); });
- connect(ui->L2Button, &QPushButton::clicked, this, [this]() { StartTimer(ui->L2Button); });
- connect(ui->L3Button, &QPushButton::clicked, this, [this]() { StartTimer(ui->L3Button); });
- connect(ui->R1Button, &QPushButton::clicked, this, [this]() { StartTimer(ui->R1Button); });
- connect(ui->R2Button, &QPushButton::clicked, this, [this]() { StartTimer(ui->R2Button); });
- connect(ui->R3Button, &QPushButton::clicked, this, [this]() { StartTimer(ui->R3Button); });
-
- connect(ui->TouchpadButton, &QPushButton::clicked, this,
- [this]() { StartTimer(ui->TouchpadButton); });
- connect(ui->OptionsButton, &QPushButton::clicked, this,
- [this]() { StartTimer(ui->OptionsButton); });
-
- connect(ui->DpadUpButton, &QPushButton::clicked, this,
- [this]() { StartTimer(ui->DpadUpButton); });
- connect(ui->DpadDownButton, &QPushButton::clicked, this,
- [this]() { StartTimer(ui->DpadDownButton); });
- connect(ui->DpadLeftButton, &QPushButton::clicked, this,
- [this]() { StartTimer(ui->DpadLeftButton); });
- connect(ui->DpadRightButton, &QPushButton::clicked, this,
- [this]() { StartTimer(ui->DpadRightButton); });
-
- connect(ui->LStickUpButton, &QPushButton::clicked, this,
- [this]() { StartTimer(ui->LStickUpButton); });
- connect(ui->LStickDownButton, &QPushButton::clicked, this,
- [this]() { StartTimer(ui->LStickDownButton); });
- connect(ui->LStickLeftButton, &QPushButton::clicked, this,
- [this]() { StartTimer(ui->LStickLeftButton); });
- connect(ui->LStickRightButton, &QPushButton::clicked, this,
- [this]() { StartTimer(ui->LStickRightButton); });
-
- connect(ui->RStickUpButton, &QPushButton::clicked, this,
- [this]() { StartTimer(ui->RStickUpButton); });
- connect(ui->RStickDownButton, &QPushButton::clicked, this,
- [this]() { StartTimer(ui->RStickDownButton); });
- connect(ui->RStickLeftButton, &QPushButton::clicked, this,
- [this]() { StartTimer(ui->RStickLeftButton); });
- connect(ui->RStickRightButton, &QPushButton::clicked, this,
- [this]() { StartTimer(ui->RStickRightButton); });
-
- connect(ui->LHalfButton, &QPushButton::clicked, this,
- [this]() { StartTimer(ui->LHalfButton); });
- connect(ui->RHalfButton, &QPushButton::clicked, this,
- [this]() { StartTimer(ui->RHalfButton); });
+ for (auto& button : ButtonsList) {
+ connect(button, &QPushButton::clicked, this, [this, &button]() { StartTimer(button); });
+ }
}
void KBMSettings::DisableMappingButtons() {
diff --git a/src/qt_gui/main_window_ui.h b/src/qt_gui/main_window_ui.h
index 2c4d4480b..4d3481c07 100644
--- a/src/qt_gui/main_window_ui.h
+++ b/src/qt_gui/main_window_ui.h
@@ -106,8 +106,6 @@ public:
toggleLabelsAct = new QAction(MainWindow);
toggleLabelsAct->setObjectName("toggleLabelsAct");
- toggleLabelsAct->setText(
- QCoreApplication::translate("MainWindow", "Show Labels Under Icons"));
toggleLabelsAct->setCheckable(true);
toggleLabelsAct->setChecked(Config::getShowLabelsUnderIcons());
@@ -413,6 +411,8 @@ public:
setThemeTokyoNight->setText("Tokyo Night");
setThemeOled->setText("OLED");
toolBar->setWindowTitle(QCoreApplication::translate("MainWindow", "toolBar", nullptr));
+ toggleLabelsAct->setText(
+ QCoreApplication::translate("MainWindow", "Show Labels Under Icons"));
} // retranslateUi
};
diff --git a/src/qt_gui/translations/ar_SA.ts b/src/qt_gui/translations/ar_SA.ts
index 7ef3c6171..e434b3259 100644
--- a/src/qt_gui/translations/ar_SA.ts
+++ b/src/qt_gui/translations/ar_SA.ts
@@ -66,7 +66,7 @@
You can delete the cheats you don't want after downloading them.
- يمكنك حذف الشفرات التي لا تريدها بعد تنزيلها.
+ يمكنك حذف الشفرات التي لا 'تريدها بعد تنزيلها.
Do you want to delete the selected file?\n%1
@@ -74,11 +74,11 @@
Select Patch File:
- إختر ملف الباتش:
+ اختر مِلَف التصحيح:
Download Patches
- تحميل الباتشات
+ تحميل ملفات التصحيح
Save
@@ -98,15 +98,15 @@
No patch selected.
- لم يتم اختيار أي تصحيح.
+ لم يتم تحديد أي مِلَف تصحيح.
Unable to open files.json for reading.
- تعذر فتح files.json للقراءة.
+ تعذّر فتح مِلَف files.json للقراءة.
No patch file found for the current serial.
- لم يتم العثور على مِلَفّ باتش للسيريال الحالي.
+ لم يتم العثور على مِلَف تصحيح للسيريال الحالي.
Unable to open the file for reading.
@@ -126,11 +126,11 @@
Options saved successfully.
- تم حفظ الخيارات بنجاح.
+ تم حفظ الإعدادات.
Invalid Source
- مصدر غير صالح
+ المصدر غير صالح
The selected source is invalid.
@@ -138,11 +138,11 @@
File Exists
- الملف موجود
+ المِلَف موجود مسبقًا
File already exists. Do you want to replace it?
- يوجد ملف بنفس الاسم. هل ترغب في استبداله؟
+ المِلَف موجود مسبقًا. هل ترغب في استبداله؟
Failed to save file:
@@ -158,7 +158,7 @@
No Cheats found for this game in this version of the selected repository,try another repository or a different version of the game.
- لم يتم العثور على شفرات لهذه اللعبة في هذه النسخة من المستودع المحدد. حاول استخدام مستودع آخر أو نسخة مختلفة من اللعبة.
+ لم يتم العثور على شفرات لهذه اللعبة في هذا الإصدار من المستودع المحدد. جرّب مستودعًا آخر أو إصدارًا مختلفًا من اللعبة.
Cheats Downloaded Successfully
@@ -182,7 +182,7 @@
Patches Downloaded Successfully! All Patches available for all games have been downloaded, there is no need to download them individually for each game as happens in Cheats. If the patch does not appear, it may be that it does not exist for the specific serial and version of the game.
- تم تنزيل التصحيحات بنجاح! تم تنزيل جميع التصحيحات لجميع الألعاب، ولا داعي لتنزيلها بشكل فردي لكل لعبة كما هو الحال مع الغش. إذا لم يظهر التحديث، قد يكون السبب أنه غير متوفر للإصدار وسيريال اللعبة المحدد.
+ تم تنزيل التصحيحات بنجاح! تم تنزيل جميع التصحيحات المتوفرة لجميع الألعاب، ولا حاجة إلى تنزيلها بشكل فردي لكل لعبة كما هو الحال مع الشفرات. إذا لم يظهر التصحيح، فقد لا يكون متوفرًا للسيريال أو الإصدار المحدد من اللعبة.
Failed to parse JSON data from HTML.
@@ -190,15 +190,15 @@
Failed to retrieve HTML page.
- .HTML فشل في استرجاع صفحة
+ فشل في جلب صفحة HTML.
The game is in version: %1
- النسخة الحالية للعبة هي: %1
+ إصدار اللعبة الحالي: %1
The downloaded patch only works on version: %1
- الباتش الذي تم تنزيله يعمل فقط على الإصدار: %1
+ التصحيح الذي تم تنزيله يعمل فقط مع الإصدار:%1
You may need to update your game.
@@ -206,7 +206,7 @@
Incompatibility Notice
- إشعار عدم التوافق
+ إشعار بعدم التوافق
Failed to open file:
@@ -238,7 +238,7 @@
Can't apply cheats before the game is started
- لا يمكن تطبيق الغش قبل بدء اللعبة.
+ لا 'يمكن تطبيق الشفرات قبل بَدْء اللعبة
Close
@@ -249,7 +249,7 @@
CheckUpdate
Auto Updater
- محدث تلقائي
+ التحديثات التلقائية
Error
@@ -261,7 +261,7 @@
The Auto Updater allows up to 60 update checks per hour.\nYou have reached this limit. Please try again later.
- يتيح التحديث التلقائي ما يصل إلى 60 عملية تحقق من التحديث في الساعة.\nلقد وصلت إلى هذا الحد. الرجاء المحاولة مرة أخرى لاحقًا.
+ تسمح التحديثات التلقائية بـ 60 عملية تحقق من التحديث في الساعة.\nلقد وصلت إلى الحد المسموح به. الرجاء المحاولة لاحقًا.
Failed to parse update information.