merge with dev branch

This commit is contained in:
Macbook 2024-10-30 23:30:41 +07:00
commit 4532a9114f
64 changed files with 1387 additions and 1004 deletions

View file

@ -16,7 +16,10 @@ jobs:
QT_VERSION: 6.6.2 QT_VERSION: 6.6.2
QIF_VERSION: 4.7 QIF_VERSION: 4.7
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }} PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
PROD_S3_ENDPOINT: ${{ secrets.PROD_S3_ENDPOINT }}
DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }} DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }}
DEV_AGW_ENDPOINT: ${{ secrets.DEV_AGW_ENDPOINT }}
DEV_S3_ENDPOINT: ${{ secrets.DEV_S3_ENDPOINT }}
steps: steps:
- name: 'Install Qt' - name: 'Install Qt'
@ -83,7 +86,10 @@ jobs:
QIF_VERSION: 4.7 QIF_VERSION: 4.7
BUILD_ARCH: 64 BUILD_ARCH: 64
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }} PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
PROD_S3_ENDPOINT: ${{ secrets.PROD_S3_ENDPOINT }}
DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }} DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }}
DEV_AGW_ENDPOINT: ${{ secrets.DEV_AGW_ENDPOINT }}
DEV_S3_ENDPOINT: ${{ secrets.DEV_S3_ENDPOINT }}
steps: steps:
- name: 'Get sources' - name: 'Get sources'
@ -146,7 +152,10 @@ jobs:
CC: cc CC: cc
CXX: c++ CXX: c++
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }} PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
PROD_S3_ENDPOINT: ${{ secrets.PROD_S3_ENDPOINT }}
DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }} DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }}
DEV_AGW_ENDPOINT: ${{ secrets.DEV_AGW_ENDPOINT }}
DEV_S3_ENDPOINT: ${{ secrets.DEV_S3_ENDPOINT }}
steps: steps:
- name: 'Setup xcode' - name: 'Setup xcode'
@ -238,7 +247,10 @@ jobs:
QT_VERSION: 6.4.3 QT_VERSION: 6.4.3
QIF_VERSION: 4.6 QIF_VERSION: 4.6
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }} PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
PROD_S3_ENDPOINT: ${{ secrets.PROD_S3_ENDPOINT }}
DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }} DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }}
DEV_AGW_ENDPOINT: ${{ secrets.DEV_AGW_ENDPOINT }}
DEV_S3_ENDPOINT: ${{ secrets.DEV_S3_ENDPOINT }}
steps: steps:
- name: 'Setup xcode' - name: 'Setup xcode'
@ -365,10 +377,13 @@ jobs:
env: env:
ANDROID_BUILD_PLATFORM: android-34 ANDROID_BUILD_PLATFORM: android-34
QT_VERSION: 6.7.2 QT_VERSION: 6.7.3
QT_MODULES: 'qtremoteobjects qt5compat qtimageformats qtshadertools' QT_MODULES: 'qtremoteobjects qt5compat qtimageformats qtshadertools'
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }} PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
PROD_S3_ENDPOINT: ${{ secrets.PROD_S3_ENDPOINT }}
DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }} DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }}
DEV_AGW_ENDPOINT: ${{ secrets.DEV_AGW_ENDPOINT }}
DEV_S3_ENDPOINT: ${{ secrets.DEV_S3_ENDPOINT }}
steps: steps:
- name: 'Install desktop Qt' - name: 'Install desktop Qt'

View file

@ -16,7 +16,10 @@ jobs:
QT_VERSION: 6.4.1 QT_VERSION: 6.4.1
QIF_VERSION: 4.5 QIF_VERSION: 4.5
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }} PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
PROD_S3_ENDPOINT: ${{ secrets.PROD_S3_ENDPOINT }}
DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }} DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }}
DEV_AGW_ENDPOINT: ${{ secrets.DEV_AGW_ENDPOINT }}
DEV_S3_ENDPOINT: ${{ secrets.DEV_S3_ENDPOINT }}
steps: steps:
- name: 'Install desktop Qt' - name: 'Install desktop Qt'

View file

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR)
set(PROJECT AmneziaVPN) set(PROJECT AmneziaVPN)
project(${PROJECT} VERSION 4.8.1.9 project(${PROJECT} VERSION 4.8.2.3
DESCRIPTION "AmneziaVPN" DESCRIPTION "AmneziaVPN"
HOMEPAGE_URL "https://amnezia.org/" HOMEPAGE_URL "https://amnezia.org/"
) )
@ -11,7 +11,7 @@ string(TIMESTAMP CURRENT_DATE "%Y-%m-%d")
set(RELEASE_DATE "${CURRENT_DATE}") set(RELEASE_DATE "${CURRENT_DATE}")
set(APP_MAJOR_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH}) set(APP_MAJOR_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
set(APP_ANDROID_VERSION_CODE 65) set(APP_ANDROID_VERSION_CODE 2069)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
set(MZ_PLATFORM_NAME "linux") set(MZ_PLATFORM_NAME "linux")

View file

@ -10,21 +10,17 @@ Amnezia is an open-source VPN client, with a key feature that enables you to dep
<br> <br>
<a href="https://github.com/amnezia-vpn/amnezia-client/releases/download/4.7.0.0/AmneziaVPN_4.7.0.0_x64.exe"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/win.png" width="150" style="max-width: 100%;"></a> <a href="https://amnezia.org/downloads"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/download.png" width="150" style="max-width: 100%;"></a>
<a href="https://github.com/amnezia-vpn/amnezia-client/releases/download/4.7.0.0/AmneziaVPN_4.7.0.0.dmg"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/mac.png" width="150" style="max-width: 100%;"></a>
<a href="https://github.com/amnezia-vpn/amnezia-client/releases/download/4.7.0.0/AmneziaVPN_Linux_4.7.0.0.tar.zip"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/lin.png" width="150" style="max-width: 100%;"></a>
<a href="https://github.com/amnezia-vpn/amnezia-client/releases/tag/4.7.0.0"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/andr.png" width="150" style="max-width: 100%;"></a>
<br>
<a href="https://play.google.com/store/search?q=amnezia+vpn&c=apps"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/play.png" width="150" style="max-width: 100%;"></a> <a href="https://play.google.com/store/search?q=amnezia+vpn&c=apps"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/play.png" width="150" style="max-width: 100%;"></a>
<a href="https://apps.apple.com/us/app/amneziavpn/id1600529900"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/apl.png" width="150" style="max-width: 100%;"></a> <a href="https://apps.apple.com/us/app/amneziavpn/id1600529900"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/apl.png" width="150" style="max-width: 100%;"></a>
[Alternative download link (mirror)](https://storage.googleapis.com/kldscp/amnezia.org/downloads)
[All releases](https://github.com/amnezia-vpn/amnezia-client/releases) [All releases](https://github.com/amnezia-vpn/amnezia-client/releases)
<br> <br>
<a href="https://www.testiny.io"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/testiny.png" height="28px"></a>
## Features ## Features
@ -37,7 +33,7 @@ Amnezia is an open-source VPN client, with a key feature that enables you to dep
## Links ## Links
- [https://amnezia.org](https://amnezia.org) - project website - [https://amnezia.org](https://amnezia.org) - project website | [Alternative link (mirror)](https://storage.googleapis.com/kldscp/amnezia.org)
- [https://www.reddit.com/r/AmneziaVPN](https://www.reddit.com/r/AmneziaVPN) - Reddit - [https://www.reddit.com/r/AmneziaVPN](https://www.reddit.com/r/AmneziaVPN) - Reddit
- [https://t.me/amnezia_vpn_en](https://t.me/amnezia_vpn_en) - Telegram support channel (English) - [https://t.me/amnezia_vpn_en](https://t.me/amnezia_vpn_en) - Telegram support channel (English)
- [https://t.me/amnezia_vpn_ir](https://t.me/amnezia_vpn_ir) - Telegram support channel (Farsi) - [https://t.me/amnezia_vpn_ir](https://t.me/amnezia_vpn_ir) - Telegram support channel (Farsi)

View file

@ -25,10 +25,11 @@ execute_process(
add_definitions(-DGIT_COMMIT_HASH="${GIT_COMMIT_HASH}") add_definitions(-DGIT_COMMIT_HASH="${GIT_COMMIT_HASH}")
add_definitions(-DPROD_AGW_PUBLIC_KEY="$ENV{PROD_AGW_PUBLIC_KEY}") add_definitions(-DPROD_AGW_PUBLIC_KEY="$ENV{PROD_AGW_PUBLIC_KEY}")
add_definitions(-DPROD_PROXY_STORAGE_KEY="$ENV{PROD_PROXY_STORAGE_KEY}") add_definitions(-DPROD_S3_ENDPOINT="$ENV{PROD_S3_ENDPOINT}")
add_definitions(-DDEV_AGW_PUBLIC_KEY="$ENV{DEV_AGW_PUBLIC_KEY}") add_definitions(-DDEV_AGW_PUBLIC_KEY="$ENV{DEV_AGW_PUBLIC_KEY}")
add_definitions(-DDEV_AGW_ENDPOINT="$ENV{DEV_AGW_ENDPOINT}") add_definitions(-DDEV_AGW_ENDPOINT="$ENV{DEV_AGW_ENDPOINT}")
add_definitions(-DDEV_S3_ENDPOINT="$ENV{DEV_S3_ENDPOINT}")
if(IOS OR MACOS_NE) if(IOS OR MACOS_NE)
set(PACKAGES ${PACKAGES} Multimedia) set(PACKAGES ${PACKAGES} Multimedia)

View file

@ -111,10 +111,11 @@ void AmneziaApplication::init()
qFatal("Android controller initialization failed"); qFatal("Android controller initialization failed");
} }
connect(AndroidController::instance(), &AndroidController::importConfigFromOutside, [this](QString data) { connect(AndroidController::instance(), &AndroidController::importConfigFromOutside, this, [this](QString data) {
m_pageController->goToPageHome(); emit m_pageController->goToPageHome();
m_importController->extractConfigFromData(data); m_importController->extractConfigFromData(data);
m_pageController->goToPageViewConfig(); data.clear();
emit m_pageController->goToPageViewConfig();
}); });
m_engine->addImageProvider(QLatin1String("installedAppImage"), new InstalledAppsImageProvider); m_engine->addImageProvider(QLatin1String("installedAppImage"), new InstalledAppsImageProvider);
@ -122,16 +123,16 @@ void AmneziaApplication::init()
#ifdef Q_OS_IOS #ifdef Q_OS_IOS
IosController::Instance()->initialize(); IosController::Instance()->initialize();
connect(IosController::Instance(), &IosController::importConfigFromOutside, [this](QString data) { connect(IosController::Instance(), &IosController::importConfigFromOutside, this, [this](QString data) {
m_pageController->goToPageHome(); emit m_pageController->goToPageHome();
m_importController->extractConfigFromData(data); m_importController->extractConfigFromData(data);
m_pageController->goToPageViewConfig(); emit m_pageController->goToPageViewConfig();
}); });
connect(IosController::Instance(), &IosController::importBackupFromOutside, [this](QString filePath) { connect(IosController::Instance(), &IosController::importBackupFromOutside, this, [this](QString filePath) {
m_pageController->goToPageHome(); emit m_pageController->goToPageHome();
m_pageController->goToPageSettingsBackup(); m_pageController->goToPageSettingsBackup();
m_settingsController->importBackupFromOutside(filePath); emit m_settingsController->importBackupFromOutside(filePath);
}); });
QTimer::singleShot(0, this, [this]() { AmneziaVPN::toggleScreenshots(m_settings->isScreenshotsEnabled()); }); QTimer::singleShot(0, this, [this]() { AmneziaVPN::toggleScreenshots(m_settings->isScreenshotsEnabled()); });

View file

@ -33,7 +33,7 @@ android.library.defaults.buildfeatures.androidresources=false
# For development copy and set local values for these parameters in local.properties # For development copy and set local values for these parameters in local.properties
#androidCompileSdkVersion=android-34 #androidCompileSdkVersion=android-34
#androidBuildToolsVersion=34.0.0 #androidBuildToolsVersion=34.0.0
#qtMinSdkVersion=24 #qtMinSdkVersion=26
#qtTargetSdkVersion=34 #qtTargetSdkVersion=34
#androidNdkVersion=26.1.10909125 #androidNdkVersion=26.1.10909125
#qtTargetAbiList=x86_64 #qtTargetAbiList=x86_64

View file

@ -1,6 +1,5 @@
package org.amnezia.vpn.protocol package org.amnezia.vpn.protocol
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.net.IpPrefix import android.net.IpPrefix
import android.net.VpnService import android.net.VpnService
@ -8,9 +7,6 @@ import android.net.VpnService.Builder
import android.os.Build import android.os.Build
import android.system.OsConstants import android.system.OsConstants
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import java.io.File
import java.io.FileOutputStream
import java.util.zip.ZipFile
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import org.amnezia.vpn.util.Log import org.amnezia.vpn.util.Log
import org.amnezia.vpn.util.net.InetNetwork import org.amnezia.vpn.util.net.InetNetwork

View file

@ -21,6 +21,7 @@ import android.os.Looper
import android.os.Message import android.os.Message
import android.os.Messenger import android.os.Messenger
import android.provider.Settings import android.provider.Settings
import android.view.MotionEvent
import android.view.WindowManager.LayoutParams import android.view.WindowManager.LayoutParams
import android.webkit.MimeTypeMap import android.webkit.MimeTypeMap
import android.widget.Toast import android.widget.Toast
@ -158,7 +159,7 @@ class AmneziaActivity : QtActivity() {
*/ */
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
Log.d(TAG, "Create Amnezia activity: $intent") Log.d(TAG, "Create Amnezia activity")
loadLibs() loadLibs()
window.apply { window.apply {
addFlags(LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) addFlags(LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
@ -200,7 +201,7 @@ class AmneziaActivity : QtActivity() {
NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED
) )
) { ) {
Log.d( Log.v(
TAG, "Notification state changed: ${it?.action}, blocked = " + TAG, "Notification state changed: ${it?.action}, blocked = " +
"${it?.getBooleanExtra(NotificationManager.EXTRA_BLOCKED_STATE, false)}" "${it?.getBooleanExtra(NotificationManager.EXTRA_BLOCKED_STATE, false)}"
) )
@ -214,7 +215,7 @@ class AmneziaActivity : QtActivity() {
override fun onNewIntent(intent: Intent?) { override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent) super.onNewIntent(intent)
Log.d(TAG, "onNewIntent: $intent") Log.v(TAG, "onNewIntent: $intent")
intent?.let(::processIntent) intent?.let(::processIntent)
} }
@ -403,7 +404,7 @@ class AmneziaActivity : QtActivity() {
@MainThread @MainThread
private fun startVpn(vpnConfig: String) { private fun startVpn(vpnConfig: String) {
getVpnProto(vpnConfig)?.let { proto -> getVpnProto(vpnConfig)?.let { proto ->
Log.d(TAG, "Proto from config: $proto, current proto: $vpnProto") Log.v(TAG, "Proto from config: $proto, current proto: $vpnProto")
if (isServiceConnected) { if (isServiceConnected) {
if (proto.serviceClass == vpnProto?.serviceClass) { if (proto.serviceClass == vpnProto?.serviceClass) {
vpnProto = proto vpnProto = proto
@ -516,7 +517,7 @@ class AmneziaActivity : QtActivity() {
startActivityForResult(it, CREATE_FILE_ACTION_CODE, ActivityResultHandler( startActivityForResult(it, CREATE_FILE_ACTION_CODE, ActivityResultHandler(
onSuccess = { onSuccess = {
it?.data?.let { uri -> it?.data?.let { uri ->
Log.d(TAG, "Save file to $uri") Log.v(TAG, "Save file to $uri")
try { try {
contentResolver.openOutputStream(uri)?.use { os -> contentResolver.openOutputStream(uri)?.use { os ->
os.bufferedWriter().use { it.write(data) } os.bufferedWriter().use { it.write(data) }
@ -565,7 +566,7 @@ class AmneziaActivity : QtActivity() {
startActivityForResult(it, OPEN_FILE_ACTION_CODE, ActivityResultHandler( startActivityForResult(it, OPEN_FILE_ACTION_CODE, ActivityResultHandler(
onAny = { onAny = {
val uri = it?.data?.toString() ?: "" val uri = it?.data?.toString() ?: ""
Log.d(TAG, "Open file: $uri") Log.v(TAG, "Open file: $uri")
mainScope.launch { mainScope.launch {
qtInitialized.await() qtInitialized.await()
QtAndroidController.onFileOpened(uri) QtAndroidController.onFileOpened(uri)
@ -720,6 +721,66 @@ class AmneziaActivity : QtActivity() {
} }
} }
// workaround for a bug in Qt that causes the mouse click event not to be handled
// also disable right-click, as it causes the application to crash
private var lastButtonState = 0
private fun MotionEvent.fixCopy(): MotionEvent = MotionEvent.obtain(
downTime,
eventTime,
action,
pointerCount,
(0 until pointerCount).map { i ->
MotionEvent.PointerProperties().apply {
getPointerProperties(i, this)
}
}.toTypedArray(),
(0 until pointerCount).map { i ->
MotionEvent.PointerCoords().apply {
getPointerCoords(i, this)
}
}.toTypedArray(),
metaState,
MotionEvent.BUTTON_PRIMARY,
xPrecision,
yPrecision,
deviceId,
edgeFlags,
source,
flags
)
private fun handleMouseEvent(ev: MotionEvent, superDispatch: (MotionEvent?) -> Boolean): Boolean {
when (ev.action) {
MotionEvent.ACTION_DOWN -> {
lastButtonState = ev.buttonState
if (ev.buttonState == MotionEvent.BUTTON_SECONDARY) return true
}
MotionEvent.ACTION_UP -> {
when (lastButtonState) {
MotionEvent.BUTTON_SECONDARY -> return true
MotionEvent.BUTTON_PRIMARY -> {
val modEvent = ev.fixCopy()
return superDispatch(modEvent).apply { modEvent.recycle() }
}
}
}
}
return superDispatch(ev)
}
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
if (ev != null && ev.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE) {
return handleMouseEvent(ev) { super.dispatchTouchEvent(it) }
}
return super.dispatchTouchEvent(ev)
}
override fun dispatchTrackballEvent(ev: MotionEvent?): Boolean {
ev?.let { return handleMouseEvent(ev) { super.dispatchTrackballEvent(it) }}
return super.dispatchTrackballEvent(ev)
}
/** /**
* Utils methods * Utils methods
*/ */

View file

@ -300,7 +300,7 @@ open class AmneziaVpnService : VpnService() {
arrayOf(ACTION_CONNECT, ACTION_DISCONNECT), ContextCompat.RECEIVER_NOT_EXPORTED arrayOf(ACTION_CONNECT, ACTION_DISCONNECT), ContextCompat.RECEIVER_NOT_EXPORTED
) { ) {
it?.action?.let { action -> it?.action?.let { action ->
Log.d(TAG, "Broadcast request received: $action") Log.v(TAG, "Broadcast request received: $action")
when (action) { when (action) {
ACTION_CONNECT -> connect() ACTION_CONNECT -> connect()
ACTION_DISCONNECT -> disconnect() ACTION_DISCONNECT -> disconnect()
@ -317,7 +317,7 @@ open class AmneziaVpnService : VpnService() {
) )
) { ) {
val state = it?.getBooleanExtra(NotificationManager.EXTRA_BLOCKED_STATE, false) val state = it?.getBooleanExtra(NotificationManager.EXTRA_BLOCKED_STATE, false)
Log.d(TAG, "Notification state changed: ${it?.action}, blocked = $state") Log.v(TAG, "Notification state changed: ${it?.action}, blocked = $state")
if (state == false) { if (state == false) {
enableNotification() enableNotification()
} else { } else {
@ -450,7 +450,7 @@ open class AmneziaVpnService : VpnService() {
serviceNotification.isNotificationEnabled() && serviceNotification.isNotificationEnabled() &&
getSystemService<PowerManager>()?.isInteractive != false getSystemService<PowerManager>()?.isInteractive != false
) { ) {
Log.d(TAG, "Launch traffic stats update") Log.v(TAG, "Launch traffic stats update")
trafficStats.reset() trafficStats.reset()
startTrafficStatsUpdateJob() startTrafficStatsUpdateJob()
} }

View file

@ -66,7 +66,7 @@ class AuthActivity : FragmentActivity() {
object : BiometricPrompt.AuthenticationCallback() { object : BiometricPrompt.AuthenticationCallback() {
override fun onAuthenticationSucceeded(result: AuthenticationResult) { override fun onAuthenticationSucceeded(result: AuthenticationResult) {
super.onAuthenticationSucceeded(result) super.onAuthenticationSucceeded(result)
Log.d(TAG, "Authentication succeeded") Log.v(TAG, "Authentication succeeded")
QtAndroidController.onAuthResult(true) QtAndroidController.onAuthResult(true)
finish() finish()
} }

View file

@ -29,20 +29,20 @@ class ImportConfigActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
Log.d(TAG, "Create Import Config Activity: $intent") Log.v(TAG, "Create Import Config Activity: $intent")
intent?.let(::readConfig) intent?.let(::readConfig)
} }
override fun onNewIntent(intent: Intent) { override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent) super.onNewIntent(intent)
Log.d(TAG, "onNewIntent: $intent") Log.v(TAG, "onNewIntent: $intent")
intent.let(::readConfig) intent.let(::readConfig)
} }
private fun readConfig(intent: Intent) { private fun readConfig(intent: Intent) {
when (intent.action) { when (intent.action) {
ACTION_SEND -> { ACTION_SEND -> {
Log.d(TAG, "Process SEND action, type: ${intent.type}") Log.v(TAG, "Process SEND action, type: ${intent.type}")
when (intent.type) { when (intent.type) {
"application/octet-stream" -> { "application/octet-stream" -> {
intent.getUriCompat()?.let { uri -> intent.getUriCompat()?.let { uri ->
@ -60,7 +60,7 @@ class ImportConfigActivity : ComponentActivity() {
} }
ACTION_VIEW -> { ACTION_VIEW -> {
Log.d(TAG, "Process VIEW action, scheme: ${intent.scheme}") Log.v(TAG, "Process VIEW action, scheme: ${intent.scheme}")
when (intent.scheme) { when (intent.scheme) {
"file", "content" -> { "file", "content" -> {
intent.data?.let { uri -> intent.data?.let { uri ->

View file

@ -62,7 +62,7 @@ class ServiceNotification(private val context: Context) {
fun buildNotification(serverName: String?, protocol: String?, state: ProtocolState): Notification { fun buildNotification(serverName: String?, protocol: String?, state: ProtocolState): Notification {
val speedString = if (state == CONNECTED) zeroSpeed else null val speedString = if (state == CONNECTED) zeroSpeed else null
Log.d(TAG, "Build notification: $serverName, $state") Log.v(TAG, "Build notification: $serverName, $state")
return notificationBuilder return notificationBuilder
.setSmallIcon(R.drawable.ic_amnezia_round) .setSmallIcon(R.drawable.ic_amnezia_round)
@ -88,17 +88,15 @@ class ServiceNotification(private val context: Context) {
fun isNotificationEnabled(): Boolean { fun isNotificationEnabled(): Boolean {
if (!context.isNotificationPermissionGranted()) return false if (!context.isNotificationPermissionGranted()) return false
if (!notificationManager.areNotificationsEnabled()) return false if (!notificationManager.areNotificationsEnabled()) return false
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { return notificationManager.getNotificationChannel(NOTIFICATION_CHANNEL_ID)?.let {
return notificationManager.getNotificationChannel(NOTIFICATION_CHANNEL_ID) it.importance != NotificationManager.IMPORTANCE_NONE
?.let { it.importance != NotificationManager.IMPORTANCE_NONE } ?: true } ?: true
}
return true
} }
@SuppressLint("MissingPermission") @SuppressLint("MissingPermission")
fun updateNotification(serverName: String?, protocol: String?, state: ProtocolState) { fun updateNotification(serverName: String?, protocol: String?, state: ProtocolState) {
if (context.isNotificationPermissionGranted()) { if (context.isNotificationPermissionGranted()) {
Log.d(TAG, "Update notification: $serverName, $state") Log.v(TAG, "Update notification: $serverName, $state")
notificationManager.notify(NOTIFICATION_ID, buildNotification(serverName, protocol, state)) notificationManager.notify(NOTIFICATION_ID, buildNotification(serverName, protocol, state))
} }
} }

View file

@ -46,7 +46,7 @@ object LibraryLoader {
System.loadLibrary(libraryName) System.loadLibrary(libraryName)
return return
} catch (_: UnsatisfiedLinkError) { } catch (_: UnsatisfiedLinkError) {
Log.d(TAG, "Failed to load library, try to extract it from apk") Log.w(TAG, "Failed to load library, try to extract it from apk")
} }
var tempFile: File? = null var tempFile: File? = null
try { try {

View file

@ -1,8 +1,6 @@
package org.amnezia.vpn.util package org.amnezia.vpn.util
import android.content.Context import android.content.Context
import android.icu.text.DateFormat
import android.icu.text.SimpleDateFormat
import android.os.Build import android.os.Build
import android.os.Process import android.os.Process
import java.io.File import java.io.File
@ -12,8 +10,6 @@ import java.nio.channels.FileChannel
import java.nio.channels.FileLock import java.nio.channels.FileLock
import java.time.LocalDateTime import java.time.LocalDateTime
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
import java.util.Date
import java.util.Locale
import java.util.concurrent.locks.ReentrantLock import java.util.concurrent.locks.ReentrantLock
import org.amnezia.vpn.util.Log.Priority.D import org.amnezia.vpn.util.Log.Priority.D
import org.amnezia.vpn.util.Log.Priority.E import org.amnezia.vpn.util.Log.Priority.E
@ -41,11 +37,7 @@ private const val LOG_MAX_FILE_SIZE = 1024 * 1024
* | | | create a report and/or terminate the process | * | | | create a report and/or terminate the process |
*/ */
object Log { object Log {
private val dateTimeFormat: Any = private val dateTimeFormat: DateTimeFormatter = DateTimeFormatter.ofPattern(DATE_TIME_PATTERN)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) DateTimeFormatter.ofPattern(DATE_TIME_PATTERN)
else object : ThreadLocal<DateFormat>() {
override fun initialValue(): DateFormat = SimpleDateFormat(DATE_TIME_PATTERN, Locale.US)
}
private lateinit var logDir: File private lateinit var logDir: File
private val logFile: File by lazy { File(logDir, LOG_FILE_NAME) } private val logFile: File by lazy { File(logDir, LOG_FILE_NAME) }
@ -143,12 +135,7 @@ object Log {
} }
private fun formatLogMsg(tag: String, msg: String, priority: Priority): String { private fun formatLogMsg(tag: String, msg: String, priority: Priority): String {
val date = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val date = LocalDateTime.now().format(dateTimeFormat)
LocalDateTime.now().format(dateTimeFormat as DateTimeFormatter)
} else {
@Suppress("UNCHECKED_CAST")
(dateTimeFormat as ThreadLocal<DateFormat>).get()?.format(Date())
}
return "$date ${Process.myPid()} ${Process.myTid()} $priority [${Thread.currentThread().name}] " + return "$date ${Process.myPid()} ${Process.myTid()} $priority [${Thread.currentThread().name}] " +
"$tag: $msg\n" "$tag: $msg\n"
} }

View file

@ -42,18 +42,12 @@ class NetworkState(
private val networkCallback: NetworkCallback by lazy(NONE) { private val networkCallback: NetworkCallback by lazy(NONE) {
object : NetworkCallback() { object : NetworkCallback() {
override fun onAvailable(network: Network) { override fun onAvailable(network: Network) {
Log.d(TAG, "onAvailable: $network") Log.v(TAG, "onAvailable: $network")
} }
override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) { override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {
Log.d(TAG, "onCapabilitiesChanged: $network, $networkCapabilities") Log.v(TAG, "onCapabilitiesChanged: $network, $networkCapabilities")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { checkNetworkState(network, networkCapabilities)
checkNetworkState(network, networkCapabilities)
} else {
handler.post {
checkNetworkState(network, networkCapabilities)
}
}
} }
private fun checkNetworkState(network: Network, networkCapabilities: NetworkCapabilities) { private fun checkNetworkState(network: Network, networkCapabilities: NetworkCapabilities) {
@ -73,11 +67,11 @@ class NetworkState(
} }
override fun onBlockedStatusChanged(network: Network, blocked: Boolean) { override fun onBlockedStatusChanged(network: Network, blocked: Boolean) {
Log.d(TAG, "onBlockedStatusChanged: $network, $blocked") Log.v(TAG, "onBlockedStatusChanged: $network, $blocked")
} }
override fun onLost(network: Network) { override fun onLost(network: Network) {
Log.d(TAG, "onLost: $network") Log.v(TAG, "onLost: $network")
} }
} }
} }
@ -87,7 +81,7 @@ class NetworkState(
Log.d(TAG, "Bind network listener") Log.d(TAG, "Bind network listener")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
connectivityManager.registerBestMatchingNetworkCallback(networkRequest, networkCallback, handler) connectivityManager.registerBestMatchingNetworkCallback(networkRequest, networkCallback, handler)
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { } else {
val numberAttempts = 300 val numberAttempts = 300
var attemptCount = 0 var attemptCount = 0
while(true) { while(true) {
@ -108,8 +102,6 @@ class NetworkState(
} }
} }
} }
} else {
connectivityManager.requestNetwork(networkRequest, networkCallback)
} }
isListenerBound = true isListenerBound = true
} }

View file

@ -66,7 +66,7 @@ open class Wireguard : Protocol() {
try { try {
delay(1000) delay(1000)
var log = getLogcat(time) var log = getLogcat(time)
Log.d(TAG, "First waiting log: $log") Log.v(TAG, "First waiting log: $log")
// check that there is a connection log, // check that there is a connection log,
// to avoid infinite connection // to avoid infinite connection
if (!log.contains("Attaching to interface")) { if (!log.contains("Attaching to interface")) {

View file

@ -130,8 +130,8 @@ class Xray : Protocol() {
LibXray.initXray(assetsPath) LibXray.initXray(assetsPath)
val geoDir = File(assetsPath, "geo").absolutePath val geoDir = File(assetsPath, "geo").absolutePath
val configPath = File(context.cacheDir, "config.json") val configPath = File(context.cacheDir, "config.json")
Log.d(TAG, "xray.location.asset: $geoDir") Log.v(TAG, "xray.location.asset: $geoDir")
Log.d(TAG, "config: $configPath") Log.v(TAG, "config: $configPath")
try { try {
configPath.writeText(configJson) configPath.writeText(configJson)
} catch (e: IOException) { } catch (e: IOException) {

View file

@ -1,6 +1,6 @@
message("Client android ${CMAKE_ANDROID_ARCH_ABI} build") message("Client android ${CMAKE_ANDROID_ARCH_ABI} build")
set(APP_ANDROID_MIN_SDK 24) set(APP_ANDROID_MIN_SDK 26)
set(ANDROID_PLATFORM "android-${APP_ANDROID_MIN_SDK}" CACHE STRING set(ANDROID_PLATFORM "android-${APP_ANDROID_MIN_SDK}" CACHE STRING
"The minimum API level supported by the application or library" FORCE) "The minimum API level supported by the application or library" FORCE)

View file

@ -1,5 +1,8 @@
#include "apiController.h" #include "apiController.h"
#include <algorithm>
#include <random>
#include <QEventLoop> #include <QEventLoop>
#include <QNetworkAccessManager> #include <QNetworkAccessManager>
#include <QNetworkReply> #include <QNetworkReply>
@ -11,6 +14,7 @@
#include "amnezia_application.h" #include "amnezia_application.h"
#include "configurators/wireguard_configurator.h" #include "configurators/wireguard_configurator.h"
#include "core/enums/apiEnums.h" #include "core/enums/apiEnums.h"
#include "utilities.h"
#include "version.h" #include "version.h"
namespace namespace
@ -33,6 +37,7 @@ namespace
constexpr char userCountryCode[] = "user_country_code"; constexpr char userCountryCode[] = "user_country_code";
constexpr char serverCountryCode[] = "server_country_code"; constexpr char serverCountryCode[] = "server_country_code";
constexpr char serviceType[] = "service_type"; constexpr char serviceType[] = "service_type";
constexpr char serviceInfo[] = "service_info";
constexpr char aesKey[] = "aes_key"; constexpr char aesKey[] = "aes_key";
constexpr char aesIv[] = "aes_iv"; constexpr char aesIv[] = "aes_iv";
@ -40,9 +45,10 @@ namespace
constexpr char apiPayload[] = "api_payload"; constexpr char apiPayload[] = "api_payload";
constexpr char keyPayload[] = "key_payload"; constexpr char keyPayload[] = "key_payload";
}
const QStringList proxyStorageUrl = { "" }; constexpr char apiConfig[] = "api_config";
constexpr char authData[] = "auth_data";
}
ErrorCode checkErrors(const QList<QSslError> &sslErrors, QNetworkReply *reply) ErrorCode checkErrors(const QList<QSslError> &sslErrors, QNetworkReply *reply)
{ {
@ -63,6 +69,28 @@ namespace
return ErrorCode::ApiConfigDownloadError; return ErrorCode::ApiConfigDownloadError;
} }
} }
bool shouldBypassProxy(QNetworkReply *reply, const QByteArray &responseBody, bool checkEncryption, const QByteArray &key = "",
const QByteArray &iv = "", const QByteArray &salt = "")
{
if (reply->error() == QNetworkReply::NetworkError::OperationCanceledError
|| reply->error() == QNetworkReply::NetworkError::TimeoutError) {
qDebug() << "Timeout occurred";
return true;
} else if (responseBody.contains("html")) {
qDebug() << "The response contains an html tag";
return true;
} else if (checkEncryption) {
try {
QSimpleCrypto::QBlockCipher blockCipher;
static_cast<void>(blockCipher.decryptAesBlockCipher(responseBody, key, iv, "", salt));
} catch (...) {
qDebug() << "Failed to decrypt the data";
return true;
}
}
return false;
}
} }
ApiController::ApiController(const QString &gatewayEndpoint, bool isDevEnvironment, QObject *parent) ApiController::ApiController(const QString &gatewayEndpoint, bool isDevEnvironment, QObject *parent)
@ -94,8 +122,8 @@ void ApiController::fillServerConfig(const QString &protocol, const ApiControlle
configStr.replace("$OPENVPN_PRIV_KEY", apiPayloadData.certRequest.privKey); configStr.replace("$OPENVPN_PRIV_KEY", apiPayloadData.certRequest.privKey);
} else if (protocol == configKey::awg) { } else if (protocol == configKey::awg) {
configStr.replace("$WIREGUARD_CLIENT_PRIVATE_KEY", apiPayloadData.wireGuardClientPrivKey); configStr.replace("$WIREGUARD_CLIENT_PRIVATE_KEY", apiPayloadData.wireGuardClientPrivKey);
auto serverConfig = QJsonDocument::fromJson(configStr.toUtf8()).object(); auto newServerConfig = QJsonDocument::fromJson(configStr.toUtf8()).object();
auto containers = serverConfig.value(config_key::containers).toArray(); auto containers = newServerConfig.value(config_key::containers).toArray();
if (containers.isEmpty()) { if (containers.isEmpty()) {
return; // todo process error return; // todo process error
} }
@ -114,25 +142,35 @@ void ApiController::fillServerConfig(const QString &protocol, const ApiControlle
containerConfig[config_key::transportPacketMagicHeader] = protocolConfig.value(config_key::transportPacketMagicHeader); containerConfig[config_key::transportPacketMagicHeader] = protocolConfig.value(config_key::transportPacketMagicHeader);
container[containerName] = containerConfig; container[containerName] = containerConfig;
containers.replace(0, container); containers.replace(0, container);
serverConfig[config_key::containers] = containers; newServerConfig[config_key::containers] = containers;
configStr = QString(QJsonDocument(serverConfig).toJson()); configStr = QString(QJsonDocument(newServerConfig).toJson());
} }
QJsonObject apiConfig = QJsonDocument::fromJson(configStr.toUtf8()).object(); QJsonObject newServerConfig = QJsonDocument::fromJson(configStr.toUtf8()).object();
serverConfig[config_key::dns1] = apiConfig.value(config_key::dns1); serverConfig[config_key::dns1] = newServerConfig.value(config_key::dns1);
serverConfig[config_key::dns2] = apiConfig.value(config_key::dns2); serverConfig[config_key::dns2] = newServerConfig.value(config_key::dns2);
serverConfig[config_key::containers] = apiConfig.value(config_key::containers); serverConfig[config_key::containers] = newServerConfig.value(config_key::containers);
serverConfig[config_key::hostName] = apiConfig.value(config_key::hostName); serverConfig[config_key::hostName] = newServerConfig.value(config_key::hostName);
if (apiConfig.value(config_key::configVersion).toInt() == ApiConfigSources::AmneziaGateway) { if (newServerConfig.value(config_key::configVersion).toInt() == ApiConfigSources::AmneziaGateway) {
serverConfig[config_key::configVersion] = apiConfig.value(config_key::configVersion); serverConfig[config_key::configVersion] = newServerConfig.value(config_key::configVersion);
serverConfig[config_key::description] = apiConfig.value(config_key::description); serverConfig[config_key::description] = newServerConfig.value(config_key::description);
serverConfig[config_key::name] = apiConfig.value(config_key::name); serverConfig[config_key::name] = newServerConfig.value(config_key::name);
} }
auto defaultContainer = apiConfig.value(config_key::defaultContainer).toString(); auto defaultContainer = newServerConfig.value(config_key::defaultContainer).toString();
serverConfig[config_key::defaultContainer] = defaultContainer; serverConfig[config_key::defaultContainer] = defaultContainer;
QVariantMap map = serverConfig.value(configKey::apiConfig).toObject().toVariantMap();
map.insert(newServerConfig.value(configKey::apiConfig).toObject().toVariantMap());
auto apiConfig = QJsonObject::fromVariantMap(map);
if (newServerConfig.value(config_key::configVersion).toInt() == ApiConfigSources::AmneziaGateway) {
apiConfig.insert(configKey::serviceInfo, QJsonDocument::fromJson(apiResponseBody).object().value(configKey::serviceInfo).toObject());
}
serverConfig[configKey::apiConfig] = apiConfig;
return; return;
} }
@ -146,6 +184,15 @@ QStringList ApiController::getProxyUrls()
QList<QSslError> sslErrors; QList<QSslError> sslErrors;
QNetworkReply *reply; QNetworkReply *reply;
QStringList proxyStorageUrl;
if (m_isDevEnvironment) {
proxyStorageUrl = QStringList { DEV_S3_ENDPOINT };
} else {
proxyStorageUrl = QStringList { PROD_S3_ENDPOINT };
}
QByteArray key = m_isDevEnvironment ? DEV_AGW_PUBLIC_KEY : PROD_AGW_PUBLIC_KEY;
for (const auto &proxyStorageUrl : proxyStorageUrl) { for (const auto &proxyStorageUrl : proxyStorageUrl) {
request.setUrl(proxyStorageUrl); request.setUrl(proxyStorageUrl);
reply = amnApp->manager()->get(request); reply = amnApp->manager()->get(request);
@ -166,11 +213,23 @@ QStringList ApiController::getProxyUrls()
EVP_PKEY *privateKey = nullptr; EVP_PKEY *privateKey = nullptr;
QByteArray responseBody; QByteArray responseBody;
try { try {
QByteArray key = PROD_PROXY_STORAGE_KEY; if (!m_isDevEnvironment) {
QSimpleCrypto::QRsa rsa; QCryptographicHash hash(QCryptographicHash::Sha512);
privateKey = rsa.getPrivateKeyFromByteArray(key, ""); hash.addData(key);
responseBody = rsa.decrypt(encryptedResponseBody, privateKey, RSA_PKCS1_PADDING); QByteArray hashResult = hash.result().toHex();
QByteArray key = QByteArray::fromHex(hashResult.left(64));
QByteArray iv = QByteArray::fromHex(hashResult.mid(64, 32));
QByteArray ba = QByteArray::fromBase64(encryptedResponseBody);
QSimpleCrypto::QBlockCipher blockCipher;
responseBody = blockCipher.decryptAesBlockCipher(ba, key, iv);
} else {
responseBody = encryptedResponseBody;
}
} catch (...) { } catch (...) {
Utils::logException();
qCritical() << "error loading private key from environment variables or decrypting payload"; qCritical() << "error loading private key from environment variables or decrypting payload";
return {}; return {};
} }
@ -292,38 +351,44 @@ ErrorCode ApiController::getServicesList(QByteArray &responseBody)
connect(reply, &QNetworkReply::sslErrors, [this, &sslErrors](const QList<QSslError> &errors) { sslErrors = errors; }); connect(reply, &QNetworkReply::sslErrors, [this, &sslErrors](const QList<QSslError> &errors) { sslErrors = errors; });
wait.exec(); wait.exec();
if (reply->error() == QNetworkReply::NetworkError::TimeoutError || reply->error() == QNetworkReply::NetworkError::OperationCanceledError) { responseBody = reply->readAll();
if (sslErrors.isEmpty() && shouldBypassProxy(reply, responseBody, false)) {
m_proxyUrls = getProxyUrls(); m_proxyUrls = getProxyUrls();
std::random_device randomDevice;
std::mt19937 generator(randomDevice());
std::shuffle(m_proxyUrls.begin(), m_proxyUrls.end(), generator);
for (const QString &proxyUrl : m_proxyUrls) { for (const QString &proxyUrl : m_proxyUrls) {
qDebug() << "Go to the next endpoint";
request.setUrl(QString("%1v1/services").arg(proxyUrl)); request.setUrl(QString("%1v1/services").arg(proxyUrl));
reply->deleteLater(); // delete the previous reply
reply = amnApp->manager()->get(request); reply = amnApp->manager()->get(request);
QObject::connect(reply, &QNetworkReply::finished, &wait, &QEventLoop::quit); QObject::connect(reply, &QNetworkReply::finished, &wait, &QEventLoop::quit);
connect(reply, &QNetworkReply::sslErrors, [this, &sslErrors](const QList<QSslError> &errors) { sslErrors = errors; }); connect(reply, &QNetworkReply::sslErrors, [this, &sslErrors](const QList<QSslError> &errors) { sslErrors = errors; });
wait.exec(); wait.exec();
if (reply->error() != QNetworkReply::NetworkError::TimeoutError
&& reply->error() != QNetworkReply::NetworkError::OperationCanceledError) { responseBody = reply->readAll();
if (!sslErrors.isEmpty() || !shouldBypassProxy(reply, responseBody, false)) {
break; break;
} }
reply->deleteLater();
} }
} }
responseBody = reply->readAll();
auto errorCode = checkErrors(sslErrors, reply); auto errorCode = checkErrors(sslErrors, reply);
reply->deleteLater(); reply->deleteLater();
return errorCode; return errorCode;
} }
ErrorCode ApiController::getConfigForService(const QString &installationUuid, const QString &userCountryCode, const QString &serviceType, ErrorCode ApiController::getConfigForService(const QString &installationUuid, const QString &userCountryCode, const QString &serviceType,
const QString &protocol, const QString &serverCountryCode, QJsonObject &serverConfig) const QString &protocol, const QString &serverCountryCode, const QJsonObject &authData,
QJsonObject &serverConfig)
{ {
#ifdef Q_OS_IOS #ifdef Q_OS_IOS
IosController::Instance()->requestInetAccess(); IosController::Instance()->requestInetAccess();
QThread::msleep(10); QThread::msleep(10);
#endif #endif
QNetworkAccessManager manager;
QNetworkRequest request; QNetworkRequest request;
request.setTransferTimeout(7000); request.setTransferTimeout(7000);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
@ -339,6 +404,9 @@ ErrorCode ApiController::getConfigForService(const QString &installationUuid, co
} }
apiPayload[configKey::serviceType] = serviceType; apiPayload[configKey::serviceType] = serviceType;
apiPayload[configKey::uuid] = installationUuid; apiPayload[configKey::uuid] = installationUuid;
if (!authData.isEmpty()) {
apiPayload[configKey::authData] = authData;
}
QSimpleCrypto::QBlockCipher blockCipher; QSimpleCrypto::QBlockCipher blockCipher;
QByteArray key = blockCipher.generatePrivateSalt(32); QByteArray key = blockCipher.generatePrivateSalt(32);
@ -361,6 +429,7 @@ ErrorCode ApiController::getConfigForService(const QString &installationUuid, co
QSimpleCrypto::QRsa rsa; QSimpleCrypto::QRsa rsa;
publicKey = rsa.getPublicKeyFromByteArray(rsaKey); publicKey = rsa.getPublicKeyFromByteArray(rsaKey);
} catch (...) { } catch (...) {
Utils::logException();
qCritical() << "error loading public key from environment variables"; qCritical() << "error loading public key from environment variables";
return ErrorCode::ApiMissingAgwPublicKey; return ErrorCode::ApiMissingAgwPublicKey;
} }
@ -370,14 +439,16 @@ ErrorCode ApiController::getConfigForService(const QString &installationUuid, co
encryptedApiPayload = blockCipher.encryptAesBlockCipher(QJsonDocument(apiPayload).toJson(), key, iv, "", salt); encryptedApiPayload = blockCipher.encryptAesBlockCipher(QJsonDocument(apiPayload).toJson(), key, iv, "", salt);
} catch (...) { // todo change error handling in QSimpleCrypto? } catch (...) { // todo change error handling in QSimpleCrypto?
Utils::logException();
qCritical() << "error when encrypting the request body"; qCritical() << "error when encrypting the request body";
return ErrorCode::ApiConfigDecryptionError;
} }
QJsonObject requestBody; QJsonObject requestBody;
requestBody[configKey::keyPayload] = QString(encryptedKeyPayload.toBase64()); requestBody[configKey::keyPayload] = QString(encryptedKeyPayload.toBase64());
requestBody[configKey::apiPayload] = QString(encryptedApiPayload.toBase64()); requestBody[configKey::apiPayload] = QString(encryptedApiPayload.toBase64());
QNetworkReply *reply = manager.post(request, QJsonDocument(requestBody).toJson()); QNetworkReply *reply = amnApp->manager()->post(request, QJsonDocument(requestBody).toJson());
QEventLoop wait; QEventLoop wait;
connect(reply, &QNetworkReply::finished, &wait, &QEventLoop::quit); connect(reply, &QNetworkReply::finished, &wait, &QEventLoop::quit);
@ -386,37 +457,43 @@ ErrorCode ApiController::getConfigForService(const QString &installationUuid, co
connect(reply, &QNetworkReply::sslErrors, [this, &sslErrors](const QList<QSslError> &errors) { sslErrors = errors; }); connect(reply, &QNetworkReply::sslErrors, [this, &sslErrors](const QList<QSslError> &errors) { sslErrors = errors; });
wait.exec(); wait.exec();
if (reply->error() == QNetworkReply::NetworkError::TimeoutError || reply->error() == QNetworkReply::NetworkError::OperationCanceledError) { auto encryptedResponseBody = reply->readAll();
if (m_proxyUrls.isEmpty()) {
m_proxyUrls = getProxyUrls(); if (sslErrors.isEmpty() && shouldBypassProxy(reply, encryptedResponseBody, true, key, iv, salt)) {
} m_proxyUrls = getProxyUrls();
std::random_device randomDevice;
std::mt19937 generator(randomDevice());
std::shuffle(m_proxyUrls.begin(), m_proxyUrls.end(), generator);
for (const QString &proxyUrl : m_proxyUrls) { for (const QString &proxyUrl : m_proxyUrls) {
qDebug() << "Go to the next endpoint";
request.setUrl(QString("%1v1/config").arg(proxyUrl)); request.setUrl(QString("%1v1/config").arg(proxyUrl));
reply = manager.post(request, QJsonDocument(requestBody).toJson()); reply->deleteLater(); // delete the previous reply
reply = amnApp->manager()->post(request, QJsonDocument(requestBody).toJson());
QObject::connect(reply, &QNetworkReply::finished, &wait, &QEventLoop::quit); QObject::connect(reply, &QNetworkReply::finished, &wait, &QEventLoop::quit);
connect(reply, &QNetworkReply::sslErrors, [this, &sslErrors](const QList<QSslError> &errors) { sslErrors = errors; }); connect(reply, &QNetworkReply::sslErrors, [this, &sslErrors](const QList<QSslError> &errors) { sslErrors = errors; });
wait.exec(); wait.exec();
if (reply->error() != QNetworkReply::NetworkError::TimeoutError
&& reply->error() != QNetworkReply::NetworkError::OperationCanceledError) { encryptedResponseBody = reply->readAll();
if (!sslErrors.isEmpty() || !shouldBypassProxy(reply, encryptedResponseBody, true, key, iv, salt)) {
break; break;
} }
reply->deleteLater();
} }
} }
auto errorCode = checkErrors(sslErrors, reply); auto errorCode = checkErrors(sslErrors, reply);
reply->deleteLater();
if (errorCode) { if (errorCode) {
return errorCode; return errorCode;
} }
auto encryptedResponseBody = reply->readAll();
reply->deleteLater();
try { try {
auto responseBody = blockCipher.decryptAesBlockCipher(encryptedResponseBody, key, iv, "", salt); auto responseBody = blockCipher.decryptAesBlockCipher(encryptedResponseBody, key, iv, "", salt);
fillServerConfig(protocol, apiPayloadData, responseBody, serverConfig); fillServerConfig(protocol, apiPayloadData, responseBody, serverConfig);
} catch (...) { // todo change error handling in QSimpleCrypto? } catch (...) { // todo change error handling in QSimpleCrypto?
Utils::logException();
qCritical() << "error when decrypting the request body"; qCritical() << "error when decrypting the request body";
return ErrorCode::ApiConfigDecryptionError;
} }
return errorCode; return errorCode;

View file

@ -21,7 +21,7 @@ public slots:
ErrorCode getServicesList(QByteArray &responseBody); ErrorCode getServicesList(QByteArray &responseBody);
ErrorCode getConfigForService(const QString &installationUuid, const QString &userCountryCode, const QString &serviceType, ErrorCode getConfigForService(const QString &installationUuid, const QString &userCountryCode, const QString &serviceType,
const QString &protocol, const QString &serverCountryCode, QJsonObject &serverConfig); const QString &protocol, const QString &serverCountryCode, const QJsonObject &authData, QJsonObject &serverConfig);
signals: signals:
void errorOccurred(ErrorCode errorCode); void errorOccurred(ErrorCode errorCode);

View file

@ -96,6 +96,7 @@ namespace amnezia
// import and install errors // import and install errors
ImportInvalidConfigError = 900, ImportInvalidConfigError = 900,
ImportOpenConfigError = 901,
// Android errors // Android errors
AndroidError = 1000, AndroidError = 1000,
@ -107,6 +108,7 @@ namespace amnezia
ApiConfigTimeoutError = 1103, ApiConfigTimeoutError = 1103,
ApiConfigSslError = 1104, ApiConfigSslError = 1104,
ApiMissingAgwPublicKey = 1105, ApiMissingAgwPublicKey = 1105,
ApiConfigDecryptionError = 1106,
// QFile errors // QFile errors
OpenError = 1200, OpenError = 1200,

View file

@ -50,6 +50,7 @@ QString errorString(ErrorCode code) {
case (ErrorCode::AddressPoolError): errorMessage = QObject::tr("VPN pool error: no available addresses"); break; case (ErrorCode::AddressPoolError): errorMessage = QObject::tr("VPN pool error: no available addresses"); break;
case (ErrorCode::ImportInvalidConfigError): errorMessage = QObject::tr("The config does not contain any containers and credentials for connecting to the server"); break; case (ErrorCode::ImportInvalidConfigError): errorMessage = QObject::tr("The config does not contain any containers and credentials for connecting to the server"); break;
case (ErrorCode::ImportOpenConfigError): errorMessage = QObject::tr("Unable to open config file"); break;
// Android errors // Android errors
case (ErrorCode::AndroidError): errorMessage = QObject::tr("VPN connection error"); break; case (ErrorCode::AndroidError): errorMessage = QObject::tr("VPN connection error"); break;
@ -61,6 +62,7 @@ QString errorString(ErrorCode code) {
case (ErrorCode::ApiConfigSslError): errorMessage = QObject::tr("SSL error occurred"); break; case (ErrorCode::ApiConfigSslError): errorMessage = QObject::tr("SSL error occurred"); break;
case (ErrorCode::ApiConfigTimeoutError): errorMessage = QObject::tr("Server response timeout on api request"); break; case (ErrorCode::ApiConfigTimeoutError): errorMessage = QObject::tr("Server response timeout on api request"); break;
case (ErrorCode::ApiMissingAgwPublicKey): errorMessage = QObject::tr("Missing AGW public key"); break; case (ErrorCode::ApiMissingAgwPublicKey): errorMessage = QObject::tr("Missing AGW public key"); break;
case (ErrorCode::ApiConfigDecryptionError): errorMessage = QObject::tr("Failed to decrypt response payload"); break;
// QFile errors // QFile errors
case(ErrorCode::OpenError): errorMessage = QObject::tr("QFile error: The file could not be opened"); break; case(ErrorCode::OpenError): errorMessage = QObject::tr("QFile error: The file could not be opened"); break;

View file

@ -78,7 +78,7 @@ bool Daemon::activate(const InterfaceConfig& config) {
return false; return false;
} }
if (supportDnsUtils() && !dnsutils()->restoreResolvers()) { if (!dnsutils()->restoreResolvers()) {
return false; return false;
} }
@ -165,10 +165,6 @@ bool Daemon::activate(const InterfaceConfig& config) {
} }
bool Daemon::maybeUpdateResolvers(const InterfaceConfig& config) { bool Daemon::maybeUpdateResolvers(const InterfaceConfig& config) {
if (!supportDnsUtils()) {
return true;
}
if ((config.m_hopType == InterfaceConfig::MultiHopExit) || if ((config.m_hopType == InterfaceConfig::MultiHopExit) ||
(config.m_hopType == InterfaceConfig::SingleHop)) { (config.m_hopType == InterfaceConfig::SingleHop)) {
QList<QHostAddress> resolvers; QList<QHostAddress> resolvers;
@ -423,13 +419,8 @@ bool Daemon::deactivate(bool emitSignals) {
} }
// Cleanup DNS // Cleanup DNS
if (supportDnsUtils() && !dnsutils()->restoreResolvers()) { if (!dnsutils()->restoreResolvers()) {
return false; logger.warning() << "Failed to restore DNS resolvers.";
}
if (!wgutils()->interfaceExists()) {
logger.warning() << "Wireguard interface does not exist.";
return false;
} }
// Cleanup peers and routing // Cleanup peers and routing
@ -449,13 +440,9 @@ bool Daemon::deactivate(bool emitSignals) {
} }
m_excludedAddrSet.clear(); m_excludedAddrSet.clear();
// Delete the interface
if (!wgutils()->deleteInterface()) {
return false;
}
m_connections.clear(); m_connections.clear();
return true; // Delete the interface
return wgutils()->deleteInterface();
} }
QString Daemon::logs() { QString Daemon::logs() {

View file

@ -69,7 +69,6 @@ class Daemon : public QObject {
virtual WireguardUtils* wgutils() const = 0; virtual WireguardUtils* wgutils() const = 0;
virtual bool supportIPUtils() const { return false; } virtual bool supportIPUtils() const { return false; }
virtual IPUtils* iputils() { return nullptr; } virtual IPUtils* iputils() { return nullptr; }
virtual bool supportDnsUtils() const { return false; }
virtual DnsUtils* dnsutils() { return nullptr; } virtual DnsUtils* dnsutils() { return nullptr; }
static bool parseStringList(const QJsonObject& obj, const QString& name, static bool parseStringList(const QJsonObject& obj, const QString& name,

View file

@ -92,6 +92,17 @@ void DaemonLocalServerConnection::parseCommand(const QByteArray& data) {
logger.debug() << "Command received:" << type; logger.debug() << "Command received:" << type;
// It is expected that sometimes the client will request backend logs
// before the first authentication. In these cases we just return empty
// logs.
if (type == "logs") {
QJsonObject obj;
obj.insert("type", "logs");
obj.insert("logs", "");
write(obj);
return;
}
if (type == "activate") { if (type == "activate") {
InterfaceConfig config; InterfaceConfig config;
if (!Daemon::parseConfig(obj, config)) { if (!Daemon::parseConfig(obj, config)) {
@ -115,8 +126,7 @@ void DaemonLocalServerConnection::parseCommand(const QByteArray& data) {
if (type == "status") { if (type == "status") {
QJsonObject obj = Daemon::instance()->getStatus(); QJsonObject obj = Daemon::instance()->getStatus();
obj.insert("type", "status"); obj.insert("type", "status");
m_socket->write(QJsonDocument(obj).toJson(QJsonDocument::Compact)); write(obj);
m_socket->write("\n");
return; return;
} }
@ -124,8 +134,7 @@ void DaemonLocalServerConnection::parseCommand(const QByteArray& data) {
QJsonObject obj; QJsonObject obj;
obj.insert("type", "logs"); obj.insert("type", "logs");
obj.insert("logs", Daemon::instance()->logs().replace("\n", "|")); obj.insert("logs", Daemon::instance()->logs().replace("\n", "|"));
m_socket->write(QJsonDocument(obj).toJson(QJsonDocument::Compact)); write(obj);
m_socket->write("\n");
return; return;
} }

View file

@ -35,7 +35,7 @@ LocalSocketController::LocalSocketController() {
connect(m_socket, &QLocalSocket::connected, this, connect(m_socket, &QLocalSocket::connected, this,
&LocalSocketController::daemonConnected); &LocalSocketController::daemonConnected);
connect(m_socket, &QLocalSocket::disconnected, this, connect(m_socket, &QLocalSocket::disconnected, this,
&LocalSocketController::disconnected); [&] { errorOccurred(QLocalSocket::PeerClosedError); });
connect(m_socket, &QLocalSocket::errorOccurred, this, connect(m_socket, &QLocalSocket::errorOccurred, this,
&LocalSocketController::errorOccurred); &LocalSocketController::errorOccurred);
connect(m_socket, &QLocalSocket::readyRead, this, connect(m_socket, &QLocalSocket::readyRead, this,

View file

@ -22,7 +22,6 @@ class LinuxDaemon final : public Daemon {
protected: protected:
WireguardUtils* wgutils() const override { return m_wgutils; } WireguardUtils* wgutils() const override { return m_wgutils; }
bool supportDnsUtils() const override { return true; }
DnsUtils* dnsutils() override { return m_dnsutils; } DnsUtils* dnsutils() override { return m_dnsutils; }
bool supportIPUtils() const override { return true; } bool supportIPUtils() const override { return true; }
IPUtils* iputils() override { return m_iputils; } IPUtils* iputils() override { return m_iputils; }

View file

@ -21,7 +21,6 @@ class MacOSDaemon final : public Daemon {
protected: protected:
WireguardUtils* wgutils() const override { return m_wgutils; } WireguardUtils* wgutils() const override { return m_wgutils; }
bool supportDnsUtils() const override { return true; }
DnsUtils* dnsutils() override { return m_dnsutils; } DnsUtils* dnsutils() override { return m_dnsutils; }
bool supportIPUtils() const override { return true; } bool supportIPUtils() const override { return true; }
IPUtils* iputils() override { return m_iputils; } IPUtils* iputils() override { return m_iputils; }

View file

@ -26,7 +26,6 @@ class WindowsDaemon final : public Daemon {
protected: protected:
bool run(Op op, const InterfaceConfig& config) override; bool run(Op op, const InterfaceConfig& config) override;
WireguardUtils* wgutils() const override { return m_wgutils; } WireguardUtils* wgutils() const override { return m_wgutils; }
bool supportDnsUtils() const override { return true; }
DnsUtils* dnsutils() override { return m_dnsutils; } DnsUtils* dnsutils() override { return m_dnsutils; }
private: private:

View file

@ -502,7 +502,7 @@ QString WindowsSplitTunnel::convertPath(const QString& path) {
// device should contain : for e.g C: // device should contain : for e.g C:
return ""; return "";
} }
QByteArray buffer(2048, 0xFF); QByteArray buffer(2048, 0xFFu);
auto ok = QueryDosDeviceW(qUtf16Printable(driveLetter), auto ok = QueryDosDeviceW(qUtf16Printable(driveLetter),
(wchar_t*)buffer.data(), buffer.size() / 2); (wchar_t*)buffer.data(), buffer.size() / 2);

View file

@ -248,7 +248,7 @@ bool WireguardUtilsWindows::updateRoutePrefix(const IPAddress& prefix) {
} }
if (result != NO_ERROR) { if (result != NO_ERROR) {
logger.error() << "Failed to create route to" logger.error() << "Failed to create route to"
<< logger.sensitive(prefix.toString()) << prefix.toString()
<< "result:" << result; << "result:" << result;
} }
return result == NO_ERROR; return result == NO_ERROR;
@ -265,7 +265,7 @@ bool WireguardUtilsWindows::deleteRoutePrefix(const IPAddress& prefix) {
} }
if (result != NO_ERROR) { if (result != NO_ERROR) {
logger.error() << "Failed to delete route to" logger.error() << "Failed to delete route to"
<< logger.sensitive(prefix.toString()) << prefix.toString()
<< "result:" << result; << "result:" << result;
} }
return result == NO_ERROR; return result == NO_ERROR;

View file

@ -21,7 +21,7 @@
#include "platforms/windows/windowsutils.h" #include "platforms/windows/windowsutils.h"
constexpr const char* VPN_NAME = "AmneziaVPN"; constexpr const char* VPN_NAME = "AmneziaVPN";
constexpr const char* WIREGUARD_DIR = "WireGuard"; constexpr const char* WIREGUARD_DIR = "AmneziaWG";
constexpr const char* DATA_DIR = "Data"; constexpr const char* DATA_DIR = "Data";
namespace { namespace {

View file

@ -89,60 +89,60 @@
<name>ConnectionController</name> <name>ConnectionController</name>
<message> <message>
<location filename="../ui/controllers/connectionController.h" line="80"/> <location filename="../ui/controllers/connectionController.h" line="80"/>
<location filename="../ui/controllers/connectionController.cpp" line="100"/> <location filename="../ui/controllers/connectionController.cpp" line="103"/>
<location filename="../ui/controllers/connectionController.cpp" line="115"/> <location filename="../ui/controllers/connectionController.cpp" line="118"/>
<location filename="../ui/controllers/connectionController.cpp" line="121"/> <location filename="../ui/controllers/connectionController.cpp" line="124"/>
<source>Connect</source> <source>Connect</source>
<translation>اتصل</translation> <translation>اتصل</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="214"/> <location filename="../ui/controllers/connectionController.cpp" line="217"/>
<source>VPN Protocols is not installed. <source>VPN Protocols is not installed.
Please install VPN container at first</source> Please install VPN container at first</source>
<translation>لم يتم تثبيت بروتوكولات VPN, من فضلك قم بتنزيل حاوية VPN اولاً</translation> <translation>لم يتم تثبيت بروتوكولات VPN, من فضلك قم بتنزيل حاوية VPN اولاً</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="81"/> <location filename="../ui/controllers/connectionController.cpp" line="84"/>
<source>Connecting...</source> <source>Connecting...</source>
<translation>اتصال...</translation> <translation>اتصال...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="86"/> <location filename="../ui/controllers/connectionController.cpp" line="89"/>
<source>Connected</source> <source>Connected</source>
<translation>تم الاتصال</translation> <translation>تم الاتصال</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="95"/> <location filename="../ui/controllers/connectionController.cpp" line="98"/>
<source>Reconnecting...</source> <source>Reconnecting...</source>
<translation>إعادة الاتصال...</translation> <translation>إعادة الاتصال...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="105"/> <location filename="../ui/controllers/connectionController.cpp" line="108"/>
<source>Disconnecting...</source> <source>Disconnecting...</source>
<translation>إنهاء الاتصال...</translation> <translation>إنهاء الاتصال...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="110"/> <location filename="../ui/controllers/connectionController.cpp" line="113"/>
<source>Preparing...</source> <source>Preparing...</source>
<translation>جاري التحضير...</translation> <translation>جاري التحضير...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="132"/> <location filename="../ui/controllers/connectionController.cpp" line="135"/>
<source>Settings updated successfully, reconnnection...</source> <source>Settings updated successfully, reconnnection...</source>
<translation>تم تحديث الاعدادات بنجاح, جاري إعادة الاتصال...</translation> <translation>تم تحديث الاعدادات بنجاح, جاري إعادة الاتصال...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="135"/> <location filename="../ui/controllers/connectionController.cpp" line="138"/>
<source>Settings updated successfully</source> <source>Settings updated successfully</source>
<translation>تم تحديث الاعدادات بنجاح</translation> <translation>تم تحديث الاعدادات بنجاح</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="209"/> <location filename="../ui/controllers/connectionController.cpp" line="212"/>
<source>The selected protocol is not supported on the current platform</source> <source>The selected protocol is not supported on the current platform</source>
<translation>البروتوكول المحدد غير مدعوم علي المنصة الحالية</translation> <translation>البروتوكول المحدد غير مدعوم علي المنصة الحالية</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="233"/> <location filename="../ui/controllers/connectionController.cpp" line="236"/>
<source>unable to create configuration</source> <source>unable to create configuration</source>
<translation>غير قادر علي إنشاء تكوين</translation> <translation>غير قادر علي إنشاء تكوين</translation>
</message> </message>
@ -253,23 +253,20 @@ Can&apos;t be disabled for current server</source>
<context> <context>
<name>ImportController</name> <name>ImportController</name>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="87"/>
<source>Unable to open file</source> <source>Unable to open file</source>
<translation>غير قادر علي فتح الملف</translation> <translation type="vanished">غير قادر علي فتح الملف</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="191"/>
<location filename="../ui/controllers/importController.cpp" line="196"/>
<source>Invalid configuration file</source> <source>Invalid configuration file</source>
<translation>ملف تكوين غير صحيح</translation> <translation type="vanished">ملف تكوين غير صحيح</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="622"/> <location filename="../ui/controllers/importController.cpp" line="623"/>
<source>Scanned %1 of %2.</source> <source>Scanned %1 of %2.</source>
<translation>تم فحص%1 من %2.</translation> <translation>تم فحص%1 من %2.</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="657"/> <location filename="../ui/controllers/importController.cpp" line="658"/>
<source>In the imported configuration, potentially dangerous lines were found:</source> <source>In the imported configuration, potentially dangerous lines were found:</source>
<translation>في التكوين المستورد، تم العثور على سطور يحتمل أن تكون خطرة:</translation> <translation>في التكوين المستورد، تم العثور على سطور يحتمل أن تكون خطرة:</translation>
</message> </message>
@ -277,24 +274,24 @@ Can&apos;t be disabled for current server</source>
<context> <context>
<name>InstallController</name> <name>InstallController</name>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="181"/> <location filename="../ui/controllers/installController.cpp" line="157"/>
<source>%1 installed successfully. </source> <source>%1 installed successfully. </source>
<translation>%1 تم التثبيت بنجاح. </translation> <translation>%1 تم التثبيت بنجاح. </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="183"/> <location filename="../ui/controllers/installController.cpp" line="159"/>
<source>%1 is already installed on the server. </source> <source>%1 is already installed on the server. </source>
<translation>%1 بالفعل مٌثبت علي الخادم. </translation> <translation>%1 بالفعل مٌثبت علي الخادم. </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="203"/> <location filename="../ui/controllers/installController.cpp" line="179"/>
<source> <source>
Added containers that were already installed on the server</source> Added containers that were already installed on the server</source>
<translation> <translation>
تمت إضافة الحاويات التي كانت مٌثبتة بالفعل علي الخادم</translation> تمت إضافة الحاويات التي كانت مٌثبتة بالفعل علي الخادم</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="283"/> <location filename="../ui/controllers/installController.cpp" line="259"/>
<source> <source>
Already installed containers were found on the server. All installed containers have been added to the application</source> Already installed containers were found on the server. All installed containers have been added to the application</source>
<translation> <translation>
@ -302,62 +299,62 @@ Already installed containers were found on the server. All installed containers
تمت إضافة جميع الحاويات المٌثبتة إلي التطبيق</translation> تمت إضافة جميع الحاويات المٌثبتة إلي التطبيق</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="541"/> <location filename="../ui/controllers/installController.cpp" line="517"/>
<source>Settings updated successfully</source> <source>Settings updated successfully</source>
<translation>تم تحديث الاعدادات بنجاح</translation> <translation>تم تحديث الاعدادات بنجاح</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="558"/> <location filename="../ui/controllers/installController.cpp" line="534"/>
<source>Server &apos;%1&apos; was rebooted</source> <source>Server &apos;%1&apos; was rebooted</source>
<translation>تمت إعادة تشغيل الخادم%1</translation> <translation>تمت إعادة تشغيل الخادم%1</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="570"/> <location filename="../ui/controllers/installController.cpp" line="546"/>
<source>Server &apos;%1&apos; was removed</source> <source>Server &apos;%1&apos; was removed</source>
<translation>تمت إزالة الخادم &apos;%1&apos;</translation> <translation>تمت إزالة الخادم &apos;%1&apos;</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="581"/> <location filename="../ui/controllers/installController.cpp" line="557"/>
<source>All containers from server &apos;%1&apos; have been removed</source> <source>All containers from server &apos;%1&apos; have been removed</source>
<translation>قد تم حذفها &apos;%1&apos; جميع الحاويات من الخادم</translation> <translation>قد تم حذفها &apos;%1&apos; جميع الحاويات من الخادم</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="599"/> <location filename="../ui/controllers/installController.cpp" line="575"/>
<source>%1 has been removed from the server &apos;%2&apos;</source> <source>%1 has been removed from the server &apos;%2&apos;</source>
<translation>%1 تم حدف &apos;%2&apos; اسم الخادم</translation> <translation>%1 تم حدف &apos;%2&apos; اسم الخادم</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="608"/> <location filename="../ui/controllers/installController.cpp" line="584"/>
<source>Api config removed</source> <source>Api config removed</source>
<translation>تم حذف تكوين Api</translation> <translation>تم حذف تكوين Api</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="630"/> <location filename="../ui/controllers/installController.cpp" line="606"/>
<source>%1 cached profile cleared</source> <source>%1 cached profile cleared</source>
<translation>تم مسح ملف تعريف %1 المخزن مؤقتًا</translation> <translation>تم مسح ملف تعريف %1 المخزن مؤقتًا</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="769"/> <location filename="../ui/controllers/installController.cpp" line="745"/>
<source>Please login as the user</source> <source>Please login as the user</source>
<translation>من فضلك قم بتسجيل الدخول كمستخدم</translation> <translation>من فضلك قم بتسجيل الدخول كمستخدم</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="797"/> <location filename="../ui/controllers/installController.cpp" line="773"/>
<source>Server added successfully</source> <source>Server added successfully</source>
<translation>تمت إضافة الخادم بنجاح</translation> <translation>تمت إضافة الخادم بنجاح</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="845"/> <location filename="../ui/controllers/installController.cpp" line="821"/>
<source>%1 installed successfully.</source> <source>%1 installed successfully.</source>
<translation>تم تحميل %1 بنجاح</translation> <translation>تم تحميل %1 بنجاح</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="877"/> <location filename="../ui/controllers/installController.cpp" line="855"/>
<source>API config reloaded</source> <source>API config reloaded</source>
<translation>تمت إعادة تحميل تكوين API</translation> <translation>تمت إعادة تحميل تكوين API</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="881"/> <location filename="../ui/controllers/installController.cpp" line="859"/>
<source>Successfully changed the country of connection to %1</source> <source>Successfully changed the country of connection to %1</source>
<translation>تم تغيير بلد الاتصال بنجاح إلى %1</translation> <translation>تم تغيير بلد الاتصال بنجاح إلى %1</translation>
</message> </message>
@ -2318,97 +2315,107 @@ Already installed containers were found on the server. All installed containers
<context> <context>
<name>PageSetupWizardConfigSource</name> <name>PageSetupWizardConfigSource</name>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
<source>Connection</source> <source>Connection</source>
<translation>الاتصال</translation> <translation>الاتصال</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
<source>Settings</source> <source>Settings</source>
<translation type="unfinished">إعدادات</translation> <translation type="unfinished">إعدادات</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
<source>Enable logs</source> <source>Enable logs</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/>
<source>Support tag</source>
<translation type="unfinished">علامة الدعم</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
<source>Copied</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="140"/>
<source>Insert the key, add a configuration file or scan the QR-code</source> <source>Insert the key, add a configuration file or scan the QR-code</source>
<translation>أدخل المفتاح، أضف ملف تكوين أو امسح رمز الاستجابة السريعة</translation> <translation>أدخل المفتاح، أضف ملف تكوين أو امسح رمز الاستجابة السريعة</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="122"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="150"/>
<source>Insert key</source> <source>Insert key</source>
<translation>أدخل مفتاح</translation> <translation>أدخل مفتاح</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="151"/>
<source>Insert</source> <source>Insert</source>
<translation>أدخل</translation> <translation>أدخل</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
<source>Continue</source> <source>Continue</source>
<translation>واصل</translation> <translation>واصل</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="161"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="189"/>
<source>Other connection options</source> <source>Other connection options</source>
<translation>اختيارات اتصال اخري</translation> <translation>اختيارات اتصال اخري</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="172"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="200"/>
<source>VPN by Amnezia</source> <source>VPN by Amnezia</source>
<translation>VPN بواسطة Amnezia</translation> <translation>VPN بواسطة Amnezia</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="173"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="201"/>
<source>Connect to classic paid and free VPN services from Amnezia</source> <source>Connect to classic paid and free VPN services from Amnezia</source>
<translation>اتصل بخدمات VPN الكلاسيكية المدفوعة والمجانية من Amnezia</translation> <translation>اتصل بخدمات VPN الكلاسيكية المدفوعة والمجانية من Amnezia</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="196"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
<source>Self-hosted VPN</source> <source>Self-hosted VPN</source>
<translation>VPN ذاتية الاستضافة</translation> <translation>VPN ذاتية الاستضافة</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="197"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="225"/>
<source>Configure Amnezia VPN on your own server</source> <source>Configure Amnezia VPN on your own server</source>
<translation>قم بتكوين Amnezia VPN على الخادم الخاص بك</translation> <translation>قم بتكوين Amnezia VPN على الخادم الخاص بك</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="217"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="245"/>
<source>Restore from backup</source> <source>Restore from backup</source>
<translation>استرجاع من ملف يحتوي علي نسخة احتياطية</translation> <translation>استرجاع من ملف يحتوي علي نسخة احتياطية</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="223"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="251"/>
<source>Open backup file</source> <source>Open backup file</source>
<translation>افتح ملف نسخ احتياطي</translation> <translation>افتح ملف نسخ احتياطي</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="252"/>
<source>Backup files (*.backup)</source> <source>Backup files (*.backup)</source>
<translation>ملفات نٌسخ احتياطية (*.backup)</translation> <translation>ملفات نٌسخ احتياطية (*.backup)</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="241"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="269"/>
<source>File with connection settings</source> <source>File with connection settings</source>
<translation>ملف إعدادات اتصال</translation> <translation>ملف إعدادات اتصال</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="249"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="277"/>
<source>Open config file</source> <source>Open config file</source>
<translation>افتح ملف تكوين</translation> <translation>افتح ملف تكوين</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
<source>QR code</source> <source>QR code</source>
<translation>رمز QR</translation> <translation>رمز QR</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="291"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="319"/>
<source>I have nothing</source> <source>I have nothing</source>
<translation>ليس لدي اي شئ</translation> <translation>ليس لدي اي شئ</translation>
</message> </message>
@ -2771,67 +2778,67 @@ Already installed containers were found on the server. All installed containers
<translation>ابحث</translation> <translation>ابحث</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="817"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="814"/>
<source>Creation date: %1</source> <source>Creation date: %1</source>
<translation>تاريخ الإنشاء: %1</translation> <translation>تاريخ الإنشاء: %1</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="825"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="822"/>
<source>Latest handshake: %1</source> <source>Latest handshake: %1</source>
<translation>اخر تصافح: %1</translation> <translation>اخر تصافح: %1</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="833"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="830"/>
<source>Data received: %1</source> <source>Data received: %1</source>
<translation>البيانات المستلمة: %1</translation> <translation>البيانات المستلمة: %1</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="841"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="838"/>
<source>Data sent: %1</source> <source>Data sent: %1</source>
<translation>البيانات المٌرسلة: %1</translation> <translation>البيانات المٌرسلة: %1</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="849"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
<source>Allowed IPs: %1</source> <source>Allowed IPs: %1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="870"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
<source>Rename</source> <source>Rename</source>
<translation>إعادة التسمية</translation> <translation>إعادة التسمية</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="916"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
<source>Client name</source> <source>Client name</source>
<translation>اسم العميل</translation> <translation>اسم العميل</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="929"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
<source>Save</source> <source>Save</source>
<translation>احفظ</translation> <translation>احفظ</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="963"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
<source>Revoke</source> <source>Revoke</source>
<translation>سحب وإبطال</translation> <translation>سحب وإبطال</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
<source>Revoke the config for a user - %1?</source> <source>Revoke the config for a user - %1?</source>
<translation>سحب وإبطال للمستخدم - %1?</translation> <translation>سحب وإبطال للمستخدم - %1?</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="968"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
<source>The user will no longer be able to connect to your server.</source> <source>The user will no longer be able to connect to your server.</source>
<translation>المستخدم لن يكون قادر علي الاتصال بعد الان.</translation> <translation>المستخدم لن يكون قادر علي الاتصال بعد الان.</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="969"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
<source>Continue</source> <source>Continue</source>
<translation>واصل</translation> <translation>واصل</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="970"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
<source>Cancel</source> <source>Cancel</source>
<translation>إلغاء</translation> <translation>إلغاء</translation>
</message> </message>
@ -2944,17 +2951,17 @@ Already installed containers were found on the server. All installed containers
<context> <context>
<name>PageStart</name> <name>PageStart</name>
<message> <message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="198"/> <location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
<source>Logging was disabled after 14 days, log files were deleted</source> <source>Logging was disabled after 14 days, log files were deleted</source>
<translation>تم تعطيل التسجيل بعد 14 يومًا، وتم حذف ملفات السجل</translation> <translation>تم تعطيل التسجيل بعد 14 يومًا، وتم حذف ملفات السجل</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/> <location filename="../ui/qml/Pages2/PageStart.qml" line="206"/>
<source>Settings restored from backup file</source> <source>Settings restored from backup file</source>
<translation>تم تحميل الإعدادات من ملف نسخة احتياطية</translation> <translation>تم تحميل الإعدادات من ملف نسخة احتياطية</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="208"/> <location filename="../ui/qml/Pages2/PageStart.qml" line="212"/>
<source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source> <source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -3293,22 +3300,22 @@ Already installed containers were found on the server. All installed containers
<translation>انتهت مدة الاتصال بالخادم</translation> <translation>انتهت مدة الاتصال بالخادم</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="55"/> <location filename="../core/errorstrings.cpp" line="56"/>
<source>VPN connection error</source> <source>VPN connection error</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="58"/> <location filename="../core/errorstrings.cpp" line="59"/>
<source>Error when retrieving configuration from API</source> <source>Error when retrieving configuration from API</source>
<translation>خطأ عند استرداد التكوين من API</translation> <translation>خطأ عند استرداد التكوين من API</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="59"/> <location filename="../core/errorstrings.cpp" line="60"/>
<source>This config has already been added to the application</source> <source>This config has already been added to the application</source>
<translation>هذا التكوين بالفعل تمت إضافتة للبرنامج</translation> <translation>هذا التكوين بالفعل تمت إضافتة للبرنامج</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="78"/> <location filename="../core/errorstrings.cpp" line="80"/>
<source>ErrorCode: %1. </source> <source>ErrorCode: %1. </source>
<translation></translation> <translation></translation>
</message> </message>
@ -3383,57 +3390,67 @@ Already installed containers were found on the server. All installed containers
<translation>التكوين لا يحتوي علي اي حاويات و اعتماد للأتصال بالخادم</translation> <translation>التكوين لا يحتوي علي اي حاويات و اعتماد للأتصال بالخادم</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="60"/> <location filename="../core/errorstrings.cpp" line="53"/>
<source>Unable to open config file</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="61"/>
<source>In the response from the server, an empty config was received</source> <source>In the response from the server, an empty config was received</source>
<translation>في الاستجابة من الخادم، تم تلقي تكوين فارغ</translation> <translation>في الاستجابة من الخادم، تم تلقي تكوين فارغ</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="61"/> <location filename="../core/errorstrings.cpp" line="62"/>
<source>SSL error occurred</source> <source>SSL error occurred</source>
<translation>حدث خطأ SSL</translation> <translation>حدث خطأ SSL</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="62"/> <location filename="../core/errorstrings.cpp" line="63"/>
<source>Server response timeout on api request</source> <source>Server response timeout on api request</source>
<translation>انتهت مهلة استجابة الخادم عند طلب واجهة برمجة التطبيقات</translation> <translation>انتهت مهلة استجابة الخادم عند طلب واجهة برمجة التطبيقات</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="63"/> <location filename="../core/errorstrings.cpp" line="64"/>
<source>Missing AGW public key</source> <source>Missing AGW public key</source>
<translation>مفتاح AGW عام مفقود</translation> <translation>مفتاح AGW عام مفقود</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="66"/> <location filename="../core/errorstrings.cpp" line="65"/>
<source>Failed to decrypt response payload</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="68"/>
<source>QFile error: The file could not be opened</source> <source>QFile error: The file could not be opened</source>
<translation>خطأ QFile: لا يمكن فتح الملف</translation> <translation>خطأ QFile: لا يمكن فتح الملف</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="67"/> <location filename="../core/errorstrings.cpp" line="69"/>
<source>QFile error: An error occurred when reading from the file</source> <source>QFile error: An error occurred when reading from the file</source>
<translation>خطأ QFile: ظهر خطأ اثناء القراءه من الملف</translation> <translation>خطأ QFile: ظهر خطأ اثناء القراءه من الملف</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="68"/> <location filename="../core/errorstrings.cpp" line="70"/>
<source>QFile error: The file could not be accessed</source> <source>QFile error: The file could not be accessed</source>
<translation>خطأ QFile: لا يمكن الوصول للملف</translation> <translation>خطأ QFile: لا يمكن الوصول للملف</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="69"/> <location filename="../core/errorstrings.cpp" line="71"/>
<source>QFile error: An unspecified error occurred</source> <source>QFile error: An unspecified error occurred</source>
<translation>خطأ QFile: ظهر خطأ غير محدد</translation> <translation>خطأ QFile: ظهر خطأ غير محدد</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="70"/> <location filename="../core/errorstrings.cpp" line="72"/>
<source>QFile error: A fatal error occurred</source> <source>QFile error: A fatal error occurred</source>
<translation>خطأ QFile: حدث خطأ فادح</translation> <translation>خطأ QFile: حدث خطأ فادح</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="71"/> <location filename="../core/errorstrings.cpp" line="73"/>
<source>QFile error: The operation was aborted</source> <source>QFile error: The operation was aborted</source>
<translation>خطأ QFile: تم إحباط العملية</translation> <translation>خطأ QFile: تم إحباط العملية</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="75"/> <location filename="../core/errorstrings.cpp" line="77"/>
<source>Internal error</source> <source>Internal error</source>
<translation>خطأ داخلي</translation> <translation>خطأ داخلي</translation>
</message> </message>
@ -4031,7 +4048,7 @@ While it offers a blend of security, stability, and speed, it&apos;s essential t
<context> <context>
<name>VpnConnection</name> <name>VpnConnection</name>
<message> <message>
<location filename="../vpnconnection.cpp" line="408"/> <location filename="../vpnconnection.cpp" line="409"/>
<source>Mbps</source> <source>Mbps</source>
<translation></translation> <translation></translation>
</message> </message>

View file

@ -88,63 +88,63 @@
<context> <context>
<name>ConnectionController</name> <name>ConnectionController</name>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="214"/> <location filename="../ui/controllers/connectionController.cpp" line="217"/>
<source>VPN Protocols is not installed. <source>VPN Protocols is not installed.
Please install VPN container at first</source> Please install VPN container at first</source>
<translation>پروتکل ویپیان نصب نشده است <translation>پروتکل ویپیان نصب نشده است
لطفا کانتینر ویپیان را نصب کنید</translation> لطفا کانتینر ویپیان را نصب کنید</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="81"/> <location filename="../ui/controllers/connectionController.cpp" line="84"/>
<source>Connecting...</source> <source>Connecting...</source>
<translation>در حال ارتباط...</translation> <translation>در حال ارتباط...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="86"/> <location filename="../ui/controllers/connectionController.cpp" line="89"/>
<source>Connected</source> <source>Connected</source>
<translation>متصل</translation> <translation>متصل</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="110"/> <location filename="../ui/controllers/connectionController.cpp" line="113"/>
<source>Preparing...</source> <source>Preparing...</source>
<translation>در حال آمادهسازی...</translation> <translation>در حال آمادهسازی...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="132"/> <location filename="../ui/controllers/connectionController.cpp" line="135"/>
<source>Settings updated successfully, reconnnection...</source> <source>Settings updated successfully, reconnnection...</source>
<translation>تنظیمات به روز رسانی شد <translation>تنظیمات به روز رسانی شد
در حال اتصال دوباره...</translation> در حال اتصال دوباره...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="135"/> <location filename="../ui/controllers/connectionController.cpp" line="138"/>
<source>Settings updated successfully</source> <source>Settings updated successfully</source>
<translation>تنظیمات با موفقیت بهروزرسانی شدند</translation> <translation>تنظیمات با موفقیت بهروزرسانی شدند</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="209"/> <location filename="../ui/controllers/connectionController.cpp" line="212"/>
<source>The selected protocol is not supported on the current platform</source> <source>The selected protocol is not supported on the current platform</source>
<translation>پروتکل انتخابشده در پلتفرم فعلی پشتیبانی نمیشود.</translation> <translation>پروتکل انتخابشده در پلتفرم فعلی پشتیبانی نمیشود.</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="233"/> <location filename="../ui/controllers/connectionController.cpp" line="236"/>
<source>unable to create configuration</source> <source>unable to create configuration</source>
<translation>نمیتوان پیکربندی را ایجاد کرد.</translation> <translation>نمیتوان پیکربندی را ایجاد کرد.</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="95"/> <location filename="../ui/controllers/connectionController.cpp" line="98"/>
<source>Reconnecting...</source> <source>Reconnecting...</source>
<translation>اتصال دوباره...</translation> <translation>اتصال دوباره...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.h" line="80"/> <location filename="../ui/controllers/connectionController.h" line="80"/>
<location filename="../ui/controllers/connectionController.cpp" line="100"/> <location filename="../ui/controllers/connectionController.cpp" line="103"/>
<location filename="../ui/controllers/connectionController.cpp" line="115"/> <location filename="../ui/controllers/connectionController.cpp" line="118"/>
<location filename="../ui/controllers/connectionController.cpp" line="121"/> <location filename="../ui/controllers/connectionController.cpp" line="124"/>
<source>Connect</source> <source>Connect</source>
<translation>اتصال</translation> <translation>اتصال</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="105"/> <location filename="../ui/controllers/connectionController.cpp" line="108"/>
<source>Disconnecting...</source> <source>Disconnecting...</source>
<translation>قطع ارتباط...</translation> <translation>قطع ارتباط...</translation>
</message> </message>
@ -258,23 +258,20 @@ Can&apos;t be disabled for current server</source>
<context> <context>
<name>ImportController</name> <name>ImportController</name>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="87"/>
<source>Unable to open file</source> <source>Unable to open file</source>
<translation>نمیتوان فایل را باز کرد.</translation> <translation type="vanished">نمیتوان فایل را باز کرد.</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="191"/>
<location filename="../ui/controllers/importController.cpp" line="196"/>
<source>Invalid configuration file</source> <source>Invalid configuration file</source>
<translation>فایل پیکربندی نامعتبر است.</translation> <translation type="vanished">فایل پیکربندی نامعتبر است.</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="622"/> <location filename="../ui/controllers/importController.cpp" line="623"/>
<source>Scanned %1 of %2.</source> <source>Scanned %1 of %2.</source>
<translation>ارزیابی %1 از %2.</translation> <translation>ارزیابی %1 از %2.</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="657"/> <location filename="../ui/controllers/importController.cpp" line="658"/>
<source>In the imported configuration, potentially dangerous lines were found:</source> <source>In the imported configuration, potentially dangerous lines were found:</source>
<translation>در پیکربندی وارد شده، خطوطی که ممکن است خطرناک باشند، یافت شدند:</translation> <translation>در پیکربندی وارد شده، خطوطی که ممکن است خطرناک باشند، یافت شدند:</translation>
</message> </message>
@ -282,86 +279,86 @@ Can&apos;t be disabled for current server</source>
<context> <context>
<name>InstallController</name> <name>InstallController</name>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="181"/> <location filename="../ui/controllers/installController.cpp" line="157"/>
<source>%1 installed successfully. </source> <source>%1 installed successfully. </source>
<translation>%1 با موفقیت نصب شد. </translation> <translation>%1 با موفقیت نصب شد. </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="183"/> <location filename="../ui/controllers/installController.cpp" line="159"/>
<source>%1 is already installed on the server. </source> <source>%1 is already installed on the server. </source>
<translation>%1 در حال حاضر بر روی سرور نصب شده است. </translation> <translation>%1 در حال حاضر بر روی سرور نصب شده است. </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="203"/> <location filename="../ui/controllers/installController.cpp" line="179"/>
<source> <source>
Added containers that were already installed on the server</source> Added containers that were already installed on the server</source>
<translation> <translation>
کانتینرهایی که بر روی سرور موجود بودند اضافه شدند</translation> کانتینرهایی که بر روی سرور موجود بودند اضافه شدند</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="283"/> <location filename="../ui/controllers/installController.cpp" line="259"/>
<source> <source>
Already installed containers were found on the server. All installed containers have been added to the application</source> Already installed containers were found on the server. All installed containers have been added to the application</source>
<translation> <translation>
کانتینرهای نصب شده بر روی سرور شناسایی شدند. تمام کانتینترهای نصب شده به نرم افزار اضافه شدند</translation> کانتینرهای نصب شده بر روی سرور شناسایی شدند. تمام کانتینترهای نصب شده به نرم افزار اضافه شدند</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="541"/> <location filename="../ui/controllers/installController.cpp" line="517"/>
<source>Settings updated successfully</source> <source>Settings updated successfully</source>
<translation>تنظیمات با موفقیت بهروزرسانی شدند</translation> <translation>تنظیمات با موفقیت بهروزرسانی شدند</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="558"/> <location filename="../ui/controllers/installController.cpp" line="534"/>
<source>Server &apos;%1&apos; was rebooted</source> <source>Server &apos;%1&apos; was rebooted</source>
<translation>سرور %1 راه اندازی مجدد شد</translation> <translation>سرور %1 راه اندازی مجدد شد</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="570"/> <location filename="../ui/controllers/installController.cpp" line="546"/>
<source>Server &apos;%1&apos; was removed</source> <source>Server &apos;%1&apos; was removed</source>
<translation>سرور %1 حذف شد</translation> <translation>سرور %1 حذف شد</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="581"/> <location filename="../ui/controllers/installController.cpp" line="557"/>
<source>All containers from server &apos;%1&apos; have been removed</source> <source>All containers from server &apos;%1&apos; have been removed</source>
<translation>تمام کانتینترها از سرور %1 حذف شدند</translation> <translation>تمام کانتینترها از سرور %1 حذف شدند</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="599"/> <location filename="../ui/controllers/installController.cpp" line="575"/>
<source>%1 has been removed from the server &apos;%2&apos;</source> <source>%1 has been removed from the server &apos;%2&apos;</source>
<translation>%1 از سرور %2 حذف شد</translation> <translation>%1 از سرور %2 حذف شد</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="608"/> <location filename="../ui/controllers/installController.cpp" line="584"/>
<source>Api config removed</source> <source>Api config removed</source>
<translation>پیکربندی API حذف شد.</translation> <translation>پیکربندی API حذف شد.</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="630"/> <location filename="../ui/controllers/installController.cpp" line="606"/>
<source>%1 cached profile cleared</source> <source>%1 cached profile cleared</source>
<translation>%1 پروفایل ذخیره شده پاک شد.</translation> <translation>%1 پروفایل ذخیره شده پاک شد.</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="769"/> <location filename="../ui/controllers/installController.cpp" line="745"/>
<source>Please login as the user</source> <source>Please login as the user</source>
<translation>لطفا به عنوان کاربر وارد شوید</translation> <translation>لطفا به عنوان کاربر وارد شوید</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="797"/> <location filename="../ui/controllers/installController.cpp" line="773"/>
<source>Server added successfully</source> <source>Server added successfully</source>
<translation>سرور با موفقیت اضافه شد</translation> <translation>سرور با موفقیت اضافه شد</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="845"/> <location filename="../ui/controllers/installController.cpp" line="821"/>
<source>%1 installed successfully.</source> <source>%1 installed successfully.</source>
<translation>%1 با موفقیت نصب شد.</translation> <translation>%1 با موفقیت نصب شد.</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="877"/> <location filename="../ui/controllers/installController.cpp" line="855"/>
<source>API config reloaded</source> <source>API config reloaded</source>
<translation>پیکربندی API دوباره بارگذاری شد.</translation> <translation>پیکربندی API دوباره بارگذاری شد.</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="881"/> <location filename="../ui/controllers/installController.cpp" line="859"/>
<source>Successfully changed the country of connection to %1</source> <source>Successfully changed the country of connection to %1</source>
<translation>کشور اتصال با موفقیت به %1 تغییر یافت.</translation> <translation>کشور اتصال با موفقیت به %1 تغییر یافت.</translation>
</message> </message>
@ -2433,7 +2430,7 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<translation type="vanished">چی داری؟</translation> <translation type="vanished">چی داری؟</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="241"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="269"/>
<source>File with connection settings</source> <source>File with connection settings</source>
<translation>فایل شامل تنظیمات اتصال</translation> <translation>فایل شامل تنظیمات اتصال</translation>
</message> </message>
@ -2442,92 +2439,102 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<translation type="vanished">فایل شامل تنظیمات اتصال یا بکآپ</translation> <translation type="vanished">فایل شامل تنظیمات اتصال یا بکآپ</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
<source>Connection</source> <source>Connection</source>
<translation>ارتباط</translation> <translation>ارتباط</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
<source>Settings</source> <source>Settings</source>
<translation type="unfinished">تنظیمات</translation> <translation type="unfinished">تنظیمات</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
<source>Enable logs</source> <source>Enable logs</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/>
<source>Support tag</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
<source>Copied</source>
<translation type="unfinished">کپی شد</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="140"/>
<source>Insert the key, add a configuration file or scan the QR-code</source> <source>Insert the key, add a configuration file or scan the QR-code</source>
<translation>کلید را وارد کنید، فایل پیکربندی را اضافه کنید یا کد QR را اسکن کنید</translation> <translation>کلید را وارد کنید، فایل پیکربندی را اضافه کنید یا کد QR را اسکن کنید</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="122"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="150"/>
<source>Insert key</source> <source>Insert key</source>
<translation>کلید را وارد کنید</translation> <translation>کلید را وارد کنید</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="151"/>
<source>Insert</source> <source>Insert</source>
<translation>وارد کردن</translation> <translation>وارد کردن</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
<source>Continue</source> <source>Continue</source>
<translation>ادامه دهید</translation> <translation>ادامه دهید</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="161"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="189"/>
<source>Other connection options</source> <source>Other connection options</source>
<translation>گزینههای اتصال دیگر</translation> <translation>گزینههای اتصال دیگر</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="172"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="200"/>
<source>VPN by Amnezia</source> <source>VPN by Amnezia</source>
<translation>VPN توسط Amnezia</translation> <translation>VPN توسط Amnezia</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="173"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="201"/>
<source>Connect to classic paid and free VPN services from Amnezia</source> <source>Connect to classic paid and free VPN services from Amnezia</source>
<translation>اتصال به سرویسهای VPN کلاسیک پولی و رایگان از Amnezia</translation> <translation>اتصال به سرویسهای VPN کلاسیک پولی و رایگان از Amnezia</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="196"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
<source>Self-hosted VPN</source> <source>Self-hosted VPN</source>
<translation>Self-hosted VPN</translation> <translation>Self-hosted VPN</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="197"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="225"/>
<source>Configure Amnezia VPN on your own server</source> <source>Configure Amnezia VPN on your own server</source>
<translation>پیکربندی VPN Amnezia بر روی سرور خودتان</translation> <translation>پیکربندی VPN Amnezia بر روی سرور خودتان</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="217"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="245"/>
<source>Restore from backup</source> <source>Restore from backup</source>
<translation>بازیابی از پشتیبان</translation> <translation>بازیابی از پشتیبان</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="223"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="251"/>
<source>Open backup file</source> <source>Open backup file</source>
<translation>باز کردن فایل پشتیبان</translation> <translation>باز کردن فایل پشتیبان</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="252"/>
<source>Backup files (*.backup)</source> <source>Backup files (*.backup)</source>
<translation>Backup files (*.backup)</translation> <translation>Backup files (*.backup)</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="249"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="277"/>
<source>Open config file</source> <source>Open config file</source>
<translation>باز کردن فایل تنظیمات</translation> <translation>باز کردن فایل تنظیمات</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
<source>QR code</source> <source>QR code</source>
<translation>QR-Code</translation> <translation>QR-Code</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="291"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="319"/>
<source>I have nothing</source> <source>I have nothing</source>
<translation>من هیچی ندارم</translation> <translation>من هیچی ندارم</translation>
</message> </message>
@ -2939,27 +2946,27 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<translation>جستجو</translation> <translation>جستجو</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="817"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="814"/>
<source>Creation date: %1</source> <source>Creation date: %1</source>
<translation>تاریخ ایجاد: %1</translation> <translation>تاریخ ایجاد: %1</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="825"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="822"/>
<source>Latest handshake: %1</source> <source>Latest handshake: %1</source>
<translation>آخرین ارتباط: %1</translation> <translation>آخرین ارتباط: %1</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="833"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="830"/>
<source>Data received: %1</source> <source>Data received: %1</source>
<translation>دادههای دریافت شده: %1</translation> <translation>دادههای دریافت شده: %1</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="841"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="838"/>
<source>Data sent: %1</source> <source>Data sent: %1</source>
<translation>دادههای ارسال شده: %1</translation> <translation>دادههای ارسال شده: %1</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="849"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
<source>Allowed IPs: %1</source> <source>Allowed IPs: %1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -2968,42 +2975,42 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<translation type="vanished">تاریخ ایجاد: </translation> <translation type="vanished">تاریخ ایجاد: </translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="870"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
<source>Rename</source> <source>Rename</source>
<translation>تغییر نام</translation> <translation>تغییر نام</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="916"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
<source>Client name</source> <source>Client name</source>
<translation>نام کلاینت</translation> <translation>نام کلاینت</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="929"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
<source>Save</source> <source>Save</source>
<translation>ذخیره</translation> <translation>ذخیره</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="963"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
<source>Revoke</source> <source>Revoke</source>
<translation>ابطال</translation> <translation>ابطال</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
<source>Revoke the config for a user - %1?</source> <source>Revoke the config for a user - %1?</source>
<translation>لغو پیکربندی برای یک کاربر - %1?</translation> <translation>لغو پیکربندی برای یک کاربر - %1?</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="968"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
<source>The user will no longer be able to connect to your server.</source> <source>The user will no longer be able to connect to your server.</source>
<translation>کاربر دیگر نمیتواند به سرور وصل شود.</translation> <translation>کاربر دیگر نمیتواند به سرور وصل شود.</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="969"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
<source>Continue</source> <source>Continue</source>
<translation>ادامه</translation> <translation>ادامه</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="970"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
<source>Cancel</source> <source>Cancel</source>
<translation>کنسل</translation> <translation>کنسل</translation>
</message> </message>
@ -3090,17 +3097,17 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<context> <context>
<name>PageStart</name> <name>PageStart</name>
<message> <message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="198"/> <location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
<source>Logging was disabled after 14 days, log files were deleted</source> <source>Logging was disabled after 14 days, log files were deleted</source>
<translation>ثبت وقایع پس از ۱۴ روز غیرفعال شد و فایلهای ثبت وقایع حذف شدند</translation> <translation>ثبت وقایع پس از ۱۴ روز غیرفعال شد و فایلهای ثبت وقایع حذف شدند</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/> <location filename="../ui/qml/Pages2/PageStart.qml" line="206"/>
<source>Settings restored from backup file</source> <source>Settings restored from backup file</source>
<translation>تنظیمات از فایل پشتیبان بازیابی شد</translation> <translation>تنظیمات از فایل پشتیبان بازیابی شد</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="208"/> <location filename="../ui/qml/Pages2/PageStart.qml" line="212"/>
<source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source> <source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -3484,22 +3491,22 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<translation>تنظیمات شامل هیچ کانتینر یا اعتبارنامهای برای اتصال به سرور نیست</translation> <translation>تنظیمات شامل هیچ کانتینر یا اعتبارنامهای برای اتصال به سرور نیست</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="55"/> <location filename="../core/errorstrings.cpp" line="56"/>
<source>VPN connection error</source> <source>VPN connection error</source>
<translation>خطای اتصال VPN</translation> <translation>خطای اتصال VPN</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="58"/> <location filename="../core/errorstrings.cpp" line="59"/>
<source>Error when retrieving configuration from API</source> <source>Error when retrieving configuration from API</source>
<translation>خطا هنگام بازیابی پیکربندی از API</translation> <translation>خطا هنگام بازیابی پیکربندی از API</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="59"/> <location filename="../core/errorstrings.cpp" line="60"/>
<source>This config has already been added to the application</source> <source>This config has already been added to the application</source>
<translation>این پیکربندی قبلاً به برنامه اضافه شده است</translation> <translation>این پیکربندی قبلاً به برنامه اضافه شده است</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="78"/> <location filename="../core/errorstrings.cpp" line="80"/>
<source>ErrorCode: %1. </source> <source>ErrorCode: %1. </source>
<translation>کد خطا: %1. </translation> <translation>کد خطا: %1. </translation>
</message> </message>
@ -3569,57 +3576,67 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<translation>VPN pool error: no available addresses</translation> <translation>VPN pool error: no available addresses</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="60"/> <location filename="../core/errorstrings.cpp" line="53"/>
<source>Unable to open config file</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="61"/>
<source>In the response from the server, an empty config was received</source> <source>In the response from the server, an empty config was received</source>
<translation>در پاسخ از سرور، پیکربندی خالی دریافت شد</translation> <translation>در پاسخ از سرور، پیکربندی خالی دریافت شد</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="61"/> <location filename="../core/errorstrings.cpp" line="62"/>
<source>SSL error occurred</source> <source>SSL error occurred</source>
<translation type="unfinished">SSL error occurred</translation> <translation type="unfinished">SSL error occurred</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="62"/> <location filename="../core/errorstrings.cpp" line="63"/>
<source>Server response timeout on api request</source> <source>Server response timeout on api request</source>
<translation>Server response timeout on api request</translation> <translation>Server response timeout on api request</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="63"/> <location filename="../core/errorstrings.cpp" line="64"/>
<source>Missing AGW public key</source> <source>Missing AGW public key</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="66"/> <location filename="../core/errorstrings.cpp" line="65"/>
<source>QFile error: The file could not be opened</source> <source>Failed to decrypt response payload</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="67"/>
<source>QFile error: An error occurred when reading from the file</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="68"/> <location filename="../core/errorstrings.cpp" line="68"/>
<source>QFile error: The file could not be accessed</source> <source>QFile error: The file could not be opened</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="69"/> <location filename="../core/errorstrings.cpp" line="69"/>
<source>QFile error: An unspecified error occurred</source> <source>QFile error: An error occurred when reading from the file</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="70"/> <location filename="../core/errorstrings.cpp" line="70"/>
<source>QFile error: A fatal error occurred</source> <source>QFile error: The file could not be accessed</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="71"/> <location filename="../core/errorstrings.cpp" line="71"/>
<source>QFile error: An unspecified error occurred</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="72"/>
<source>QFile error: A fatal error occurred</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="73"/>
<source>QFile error: The operation was aborted</source> <source>QFile error: The operation was aborted</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="75"/> <location filename="../core/errorstrings.cpp" line="77"/>
<source>Internal error</source> <source>Internal error</source>
<translation>Internal error</translation> <translation>Internal error</translation>
</message> </message>
@ -4239,7 +4256,7 @@ For more detailed information, you can
<context> <context>
<name>VpnConnection</name> <name>VpnConnection</name>
<message> <message>
<location filename="../vpnconnection.cpp" line="408"/> <location filename="../vpnconnection.cpp" line="409"/>
<source>Mbps</source> <source>Mbps</source>
<translation>Mbps</translation> <translation>Mbps</translation>
</message> </message>

View file

@ -89,61 +89,61 @@
<name>ConnectionController</name> <name>ConnectionController</name>
<message> <message>
<location filename="../ui/controllers/connectionController.h" line="80"/> <location filename="../ui/controllers/connectionController.h" line="80"/>
<location filename="../ui/controllers/connectionController.cpp" line="100"/> <location filename="../ui/controllers/connectionController.cpp" line="103"/>
<location filename="../ui/controllers/connectionController.cpp" line="115"/> <location filename="../ui/controllers/connectionController.cpp" line="118"/>
<location filename="../ui/controllers/connectionController.cpp" line="121"/> <location filename="../ui/controllers/connectionController.cpp" line="124"/>
<source>Connect</source> <source>Connect</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="214"/> <location filename="../ui/controllers/connectionController.cpp" line="217"/>
<source>VPN Protocols is not installed. <source>VPN Protocols is not installed.
Please install VPN container at first</source> Please install VPN container at first</source>
<translation> ि . <translation> ि .
ि </translation> ि </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="86"/> <location filename="../ui/controllers/connectionController.cpp" line="89"/>
<source>Connected</source> <source>Connected</source>
<translation> </translation> <translation> </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="209"/> <location filename="../ui/controllers/connectionController.cpp" line="212"/>
<source>The selected protocol is not supported on the current platform</source> <source>The selected protocol is not supported on the current platform</source>
<translation>ि ि </translation> <translation>ि ि </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="233"/> <location filename="../ui/controllers/connectionController.cpp" line="236"/>
<source>unable to create configuration</source> <source>unable to create configuration</source>
<translation>ि </translation> <translation>ि </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="81"/> <location filename="../ui/controllers/connectionController.cpp" line="84"/>
<source>Connecting...</source> <source>Connecting...</source>
<translation>...</translation> <translation>...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="95"/> <location filename="../ui/controllers/connectionController.cpp" line="98"/>
<source>Reconnecting...</source> <source>Reconnecting...</source>
<translation> ...</translation> <translation> ...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="105"/> <location filename="../ui/controllers/connectionController.cpp" line="108"/>
<source>Disconnecting...</source> <source>Disconnecting...</source>
<translation>ि ...</translation> <translation>ि ...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="110"/> <location filename="../ui/controllers/connectionController.cpp" line="113"/>
<source>Preparing...</source> <source>Preparing...</source>
<translation> ...</translation> <translation> ...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="132"/> <location filename="../ui/controllers/connectionController.cpp" line="135"/>
<source>Settings updated successfully, reconnnection...</source> <source>Settings updated successfully, reconnnection...</source>
<translation>ि ...</translation> <translation>ि ...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="135"/> <location filename="../ui/controllers/connectionController.cpp" line="138"/>
<source>Settings updated successfully</source> <source>Settings updated successfully</source>
<translation>ि </translation> <translation>ि </translation>
</message> </message>
@ -254,23 +254,20 @@ Can&apos;t be disabled for current server</source>
<context> <context>
<name>ImportController</name> <name>ImportController</name>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="87"/>
<source>Unable to open file</source> <source>Unable to open file</source>
<translation> </translation> <translation type="vanished"> </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="191"/>
<location filename="../ui/controllers/importController.cpp" line="196"/>
<source>Invalid configuration file</source> <source>Invalid configuration file</source>
<translation> ि </translation> <translation type="vanished"> ि </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="622"/> <location filename="../ui/controllers/importController.cpp" line="623"/>
<source>Scanned %1 of %2.</source> <source>Scanned %1 of %2.</source>
<translation>%2 %1 ि .</translation> <translation>%2 %1 ि .</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="657"/> <location filename="../ui/controllers/importController.cpp" line="658"/>
<source>In the imported configuration, potentially dangerous lines were found:</source> <source>In the imported configuration, potentially dangerous lines were found:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -278,86 +275,86 @@ Can&apos;t be disabled for current server</source>
<context> <context>
<name>InstallController</name> <name>InstallController</name>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="181"/> <location filename="../ui/controllers/installController.cpp" line="157"/>
<source>%1 installed successfully. </source> <source>%1 installed successfully. </source>
<translation>%1 ि . </translation> <translation>%1 ि . </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="183"/> <location filename="../ui/controllers/installController.cpp" line="159"/>
<source>%1 is already installed on the server. </source> <source>%1 is already installed on the server. </source>
<translation>%1 ि . </translation> <translation>%1 ि . </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="203"/> <location filename="../ui/controllers/installController.cpp" line="179"/>
<source> <source>
Added containers that were already installed on the server</source> Added containers that were already installed on the server</source>
<translation> <translation>
ि </translation> ि </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="283"/> <location filename="../ui/controllers/installController.cpp" line="259"/>
<source> <source>
Already installed containers were found on the server. All installed containers have been added to the application</source> Already installed containers were found on the server. All installed containers have been added to the application</source>
<translation> <translation>
ि ि ि ि </translation> ि ि ि ि </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="541"/> <location filename="../ui/controllers/installController.cpp" line="517"/>
<source>Settings updated successfully</source> <source>Settings updated successfully</source>
<translation>ि </translation> <translation>ि </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="558"/> <location filename="../ui/controllers/installController.cpp" line="534"/>
<source>Server &apos;%1&apos; was rebooted</source> <source>Server &apos;%1&apos; was rebooted</source>
<translation> &apos;%1&apos; ि </translation> <translation> &apos;%1&apos; ि </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="570"/> <location filename="../ui/controllers/installController.cpp" line="546"/>
<source>Server &apos;%1&apos; was removed</source> <source>Server &apos;%1&apos; was removed</source>
<translation> &apos;%1&apos; ि </translation> <translation> &apos;%1&apos; ि </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="581"/> <location filename="../ui/controllers/installController.cpp" line="557"/>
<source>All containers from server &apos;%1&apos; have been removed</source> <source>All containers from server &apos;%1&apos; have been removed</source>
<translation> &apos;%1&apos; ि </translation> <translation> &apos;%1&apos; ि </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="599"/> <location filename="../ui/controllers/installController.cpp" line="575"/>
<source>%1 has been removed from the server &apos;%2&apos;</source> <source>%1 has been removed from the server &apos;%2&apos;</source>
<translation>%1 &apos;%2&apos; ि </translation> <translation>%1 &apos;%2&apos; ि </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="608"/> <location filename="../ui/controllers/installController.cpp" line="584"/>
<source>Api config removed</source> <source>Api config removed</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="630"/> <location filename="../ui/controllers/installController.cpp" line="606"/>
<source>%1 cached profile cleared</source> <source>%1 cached profile cleared</source>
<translation>%1 </translation> <translation>%1 </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="769"/> <location filename="../ui/controllers/installController.cpp" line="745"/>
<source>Please login as the user</source> <source>Please login as the user</source>
<translation> ि </translation> <translation> ि </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="797"/> <location filename="../ui/controllers/installController.cpp" line="773"/>
<source>Server added successfully</source> <source>Server added successfully</source>
<translation> </translation> <translation> </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="845"/> <location filename="../ui/controllers/installController.cpp" line="821"/>
<source>%1 installed successfully.</source> <source>%1 installed successfully.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="877"/> <location filename="../ui/controllers/installController.cpp" line="855"/>
<source>API config reloaded</source> <source>API config reloaded</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="881"/> <location filename="../ui/controllers/installController.cpp" line="859"/>
<source>Successfully changed the country of connection to %1</source> <source>Successfully changed the country of connection to %1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -2382,97 +2379,107 @@ Already installed containers were found on the server. All installed containers
<translation type="vanished"> ि </translation> <translation type="vanished"> ि </translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
<source>Connection</source> <source>Connection</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
<source>Settings</source> <source>Settings</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
<source>Enable logs</source> <source>Enable logs</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/>
<source>Insert the key, add a configuration file or scan the QR-code</source> <source>Support tag</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="122"/>
<source>Insert key</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
<source>Copied</source>
<translation type="unfinished"> ि </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="140"/>
<source>Insert the key, add a configuration file or scan the QR-code</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="150"/>
<source>Insert key</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="151"/>
<source>Insert</source> <source>Insert</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
<source>Continue</source> <source>Continue</source>
<translation type="unfinished"> </translation> <translation type="unfinished"> </translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="161"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="189"/>
<source>Other connection options</source> <source>Other connection options</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="172"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="200"/>
<source>VPN by Amnezia</source> <source>VPN by Amnezia</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="173"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="201"/>
<source>Connect to classic paid and free VPN services from Amnezia</source> <source>Connect to classic paid and free VPN services from Amnezia</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="196"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
<source>Self-hosted VPN</source> <source>Self-hosted VPN</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="197"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="225"/>
<source>Configure Amnezia VPN on your own server</source> <source>Configure Amnezia VPN on your own server</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="217"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="245"/>
<source>Restore from backup</source> <source>Restore from backup</source>
<translation type="unfinished"> </translation> <translation type="unfinished"> </translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="223"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="251"/>
<source>Open backup file</source> <source>Open backup file</source>
<translation type="unfinished"> </translation> <translation type="unfinished"> </translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="252"/>
<source>Backup files (*.backup)</source> <source>Backup files (*.backup)</source>
<translation type="unfinished"> (*.backup)</translation> <translation type="unfinished"> (*.backup)</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="241"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="269"/>
<source>File with connection settings</source> <source>File with connection settings</source>
<translation> ि </translation> <translation> ि </translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="249"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="277"/>
<source>Open config file</source> <source>Open config file</source>
<translation>ि </translation> <translation>ि </translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
<source>QR code</source> <source>QR code</source>
<translation> ि</translation> <translation> ि</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="291"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="319"/>
<source>I have nothing</source> <source>I have nothing</source>
<translation type="unfinished"> </translation> <translation type="unfinished"> </translation>
</message> </message>
@ -2857,27 +2864,27 @@ Already installed containers were found on the server. All installed containers
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="817"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="814"/>
<source>Creation date: %1</source> <source>Creation date: %1</source>
<translation>ि ि: %1</translation> <translation>ि ि: %1</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="825"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="822"/>
<source>Latest handshake: %1</source> <source>Latest handshake: %1</source>
<translation> ि: %1</translation> <translation> ि: %1</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="833"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="830"/>
<source>Data received: %1</source> <source>Data received: %1</source>
<translation> : %1</translation> <translation> : %1</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="841"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="838"/>
<source>Data sent: %1</source> <source>Data sent: %1</source>
<translation> : %1</translation> <translation> : %1</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="849"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
<source>Allowed IPs: %1</source> <source>Allowed IPs: %1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -2886,42 +2893,42 @@ Already installed containers were found on the server. All installed containers
<translation type="vanished">ि िि: </translation> <translation type="vanished">ि िि: </translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="870"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
<source>Rename</source> <source>Rename</source>
<translation> </translation> <translation> </translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="916"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
<source>Client name</source> <source>Client name</source>
<translation> </translation> <translation> </translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="929"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
<source>Save</source> <source>Save</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="963"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
<source>Revoke</source> <source>Revoke</source>
<translation>ि </translation> <translation>ि </translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
<source>Revoke the config for a user - %1?</source> <source>Revoke the config for a user - %1?</source>
<translation>ि ि ि ि - %1?</translation> <translation>ि ि ि ि - %1?</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="968"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
<source>The user will no longer be able to connect to your server.</source> <source>The user will no longer be able to connect to your server.</source>
<translation> .</translation> <translation> .</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="969"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
<source>Continue</source> <source>Continue</source>
<translation> </translation> <translation> </translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="970"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
<source>Cancel</source> <source>Cancel</source>
<translation> </translation> <translation> </translation>
</message> </message>
@ -3039,17 +3046,17 @@ Already installed containers were found on the server. All installed containers
<context> <context>
<name>PageStart</name> <name>PageStart</name>
<message> <message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="198"/> <location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
<source>Logging was disabled after 14 days, log files were deleted</source> <source>Logging was disabled after 14 days, log files were deleted</source>
<translation>14 ि ि , </translation> <translation>14 ि ि , </translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/> <location filename="../ui/qml/Pages2/PageStart.qml" line="206"/>
<source>Settings restored from backup file</source> <source>Settings restored from backup file</source>
<translation type="unfinished"> ि ि </translation> <translation type="unfinished"> ि ि </translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="208"/> <location filename="../ui/qml/Pages2/PageStart.qml" line="212"/>
<source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source> <source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -3398,42 +3405,52 @@ Already installed containers were found on the server. All installed containers
<translation> </translation> <translation> </translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="55"/> <location filename="../core/errorstrings.cpp" line="53"/>
<source>Unable to open config file</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="56"/>
<source>VPN connection error</source> <source>VPN connection error</source>
<translation>VPN ि</translation> <translation>VPN ि</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="58"/> <location filename="../core/errorstrings.cpp" line="59"/>
<source>Error when retrieving configuration from API</source> <source>Error when retrieving configuration from API</source>
<translation> ि ि</translation> <translation> ि ि</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="59"/> <location filename="../core/errorstrings.cpp" line="60"/>
<source>This config has already been added to the application</source> <source>This config has already been added to the application</source>
<translation> ि ि </translation> <translation> ि ि </translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="60"/> <location filename="../core/errorstrings.cpp" line="61"/>
<source>In the response from the server, an empty config was received</source> <source>In the response from the server, an empty config was received</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="61"/> <location filename="../core/errorstrings.cpp" line="62"/>
<source>SSL error occurred</source> <source>SSL error occurred</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="62"/> <location filename="../core/errorstrings.cpp" line="63"/>
<source>Server response timeout on api request</source> <source>Server response timeout on api request</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="63"/> <location filename="../core/errorstrings.cpp" line="64"/>
<source>Missing AGW public key</source> <source>Missing AGW public key</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="78"/> <location filename="../core/errorstrings.cpp" line="65"/>
<source>Failed to decrypt response payload</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="80"/>
<source>ErrorCode: %1. </source> <source>ErrorCode: %1. </source>
<translation>ErrorCode: %1. </translation> <translation>ErrorCode: %1. </translation>
</message> </message>
@ -3498,37 +3515,37 @@ Already installed containers were found on the server. All installed containers
<translation>ि ि ि </translation> <translation>ि ि ि </translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="66"/> <location filename="../core/errorstrings.cpp" line="68"/>
<source>QFile error: The file could not be opened</source> <source>QFile error: The file could not be opened</source>
<translation>Qफ़ ि: </translation> <translation>Qफ़ ि: </translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="67"/> <location filename="../core/errorstrings.cpp" line="69"/>
<source>QFile error: An error occurred when reading from the file</source> <source>QFile error: An error occurred when reading from the file</source>
<translation>Qफ़ ि: ि </translation> <translation>Qफ़ ि: ि </translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="68"/> <location filename="../core/errorstrings.cpp" line="70"/>
<source>QFile error: The file could not be accessed</source> <source>QFile error: The file could not be accessed</source>
<translation>Qफ़ ि: </translation> <translation>Qफ़ ि: </translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="69"/> <location filename="../core/errorstrings.cpp" line="71"/>
<source>QFile error: An unspecified error occurred</source> <source>QFile error: An unspecified error occurred</source>
<translation>Qफ़ ि: िि ि </translation> <translation>Qफ़ ि: िि ि </translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="70"/> <location filename="../core/errorstrings.cpp" line="72"/>
<source>QFile error: A fatal error occurred</source> <source>QFile error: A fatal error occurred</source>
<translation>Qफ़ ि: ि </translation> <translation>Qफ़ ि: ि </translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="71"/> <location filename="../core/errorstrings.cpp" line="73"/>
<source>QFile error: The operation was aborted</source> <source>QFile error: The operation was aborted</source>
<translation>Qफ़ ि: ि ि </translation> <translation>Qफ़ ि: ि ि </translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="75"/> <location filename="../core/errorstrings.cpp" line="77"/>
<source>Internal error</source> <source>Internal error</source>
<translation>ि ि</translation> <translation>ि ि</translation>
</message> </message>
@ -4127,7 +4144,7 @@ While it offers a blend of security, stability, and speed, it&apos;s essential t
<context> <context>
<name>VpnConnection</name> <name>VpnConnection</name>
<message> <message>
<location filename="../vpnconnection.cpp" line="408"/> <location filename="../vpnconnection.cpp" line="409"/>
<source>Mbps</source> <source>Mbps</source>
<translation></translation> <translation></translation>
</message> </message>

View file

@ -88,62 +88,62 @@
<context> <context>
<name>ConnectionController</name> <name>ConnectionController</name>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="214"/> <location filename="../ui/controllers/connectionController.cpp" line="217"/>
<source>VPN Protocols is not installed. <source>VPN Protocols is not installed.
Please install VPN container at first</source> Please install VPN container at first</source>
<translation>VPN ကက <translation>VPN ကက
က VPN ကက </translation> က VPN ကက </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="81"/> <location filename="../ui/controllers/connectionController.cpp" line="84"/>
<source>Connecting...</source> <source>Connecting...</source>
<translation>က...</translation> <translation>က...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="86"/> <location filename="../ui/controllers/connectionController.cpp" line="89"/>
<source>Connected</source> <source>Connected</source>
<translation>က</translation> <translation>က</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="110"/> <location filename="../ui/controllers/connectionController.cpp" line="113"/>
<source>Preparing...</source> <source>Preparing...</source>
<translation>...</translation> <translation>...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="132"/> <location filename="../ui/controllers/connectionController.cpp" line="135"/>
<source>Settings updated successfully, reconnnection...</source> <source>Settings updated successfully, reconnnection...</source>
<translation>ကက က...</translation> <translation>ကက က...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="135"/> <location filename="../ui/controllers/connectionController.cpp" line="138"/>
<source>Settings updated successfully</source> <source>Settings updated successfully</source>
<translation>ကက </translation> <translation>ကက </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="209"/> <location filename="../ui/controllers/connectionController.cpp" line="212"/>
<source>The selected protocol is not supported on the current platform</source> <source>The selected protocol is not supported on the current platform</source>
<translation> ကက ကက က</translation> <translation> ကက ကက က</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="233"/> <location filename="../ui/controllers/connectionController.cpp" line="236"/>
<source>unable to create configuration</source> <source>unable to create configuration</source>
<translation>configuration </translation> <translation>configuration </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="95"/> <location filename="../ui/controllers/connectionController.cpp" line="98"/>
<source>Reconnecting...</source> <source>Reconnecting...</source>
<translation>က...</translation> <translation>က...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.h" line="80"/> <location filename="../ui/controllers/connectionController.h" line="80"/>
<location filename="../ui/controllers/connectionController.cpp" line="100"/> <location filename="../ui/controllers/connectionController.cpp" line="103"/>
<location filename="../ui/controllers/connectionController.cpp" line="115"/> <location filename="../ui/controllers/connectionController.cpp" line="118"/>
<location filename="../ui/controllers/connectionController.cpp" line="121"/> <location filename="../ui/controllers/connectionController.cpp" line="124"/>
<source>Connect</source> <source>Connect</source>
<translation>က</translation> <translation>က</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="105"/> <location filename="../ui/controllers/connectionController.cpp" line="108"/>
<source>Disconnecting...</source> <source>Disconnecting...</source>
<translation>က...</translation> <translation>က...</translation>
</message> </message>
@ -254,23 +254,20 @@ Can&apos;t be disabled for current server</source>
<context> <context>
<name>ImportController</name> <name>ImportController</name>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="87"/>
<source>Unable to open file</source> <source>Unable to open file</source>
<translation>က</translation> <translation type="vanished">က</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="191"/>
<location filename="../ui/controllers/importController.cpp" line="196"/>
<source>Invalid configuration file</source> <source>Invalid configuration file</source>
<translation>Configuration က</translation> <translation type="vanished">Configuration က</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="622"/> <location filename="../ui/controllers/importController.cpp" line="623"/>
<source>Scanned %1 of %2.</source> <source>Scanned %1 of %2.</source>
<translation>%2 %1 က က.</translation> <translation>%2 %1 က က.</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="657"/> <location filename="../ui/controllers/importController.cpp" line="658"/>
<source>In the imported configuration, potentially dangerous lines were found:</source> <source>In the imported configuration, potentially dangerous lines were found:</source>
<translation> configuration က :</translation> <translation> configuration က :</translation>
</message> </message>
@ -278,86 +275,86 @@ Can&apos;t be disabled for current server</source>
<context> <context>
<name>InstallController</name> <name>InstallController</name>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="181"/> <location filename="../ui/controllers/installController.cpp" line="157"/>
<source>%1 installed successfully. </source> <source>%1 installed successfully. </source>
<translation>%1 က . </translation> <translation>%1 က . </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="183"/> <location filename="../ui/controllers/installController.cpp" line="159"/>
<source>%1 is already installed on the server. </source> <source>%1 is already installed on the server. </source>
<translation>%1 က . </translation> <translation>%1 က . </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="203"/> <location filename="../ui/controllers/installController.cpp" line="179"/>
<source> <source>
Added containers that were already installed on the server</source> Added containers that were already installed on the server</source>
<translation> <translation>
ကက </translation> ကက </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="283"/> <location filename="../ui/controllers/installController.cpp" line="259"/>
<source> <source>
Already installed containers were found on the server. All installed containers have been added to the application</source> Already installed containers were found on the server. All installed containers have been added to the application</source>
<translation> <translation>
ကက ကက က </translation> ကက ကက က </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="541"/> <location filename="../ui/controllers/installController.cpp" line="517"/>
<source>Settings updated successfully</source> <source>Settings updated successfully</source>
<translation>ကက </translation> <translation>ကက </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="558"/> <location filename="../ui/controllers/installController.cpp" line="534"/>
<source>Server &apos;%1&apos; was rebooted</source> <source>Server &apos;%1&apos; was rebooted</source>
<translation> &apos;%1&apos; က </translation> <translation> &apos;%1&apos; က </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="570"/> <location filename="../ui/controllers/installController.cpp" line="546"/>
<source>Server &apos;%1&apos; was removed</source> <source>Server &apos;%1&apos; was removed</source>
<translation> &apos;%1&apos; က </translation> <translation> &apos;%1&apos; က </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="581"/> <location filename="../ui/controllers/installController.cpp" line="557"/>
<source>All containers from server &apos;%1&apos; have been removed</source> <source>All containers from server &apos;%1&apos; have been removed</source>
<translation> &apos;%1&apos; ကက က</translation> <translation> &apos;%1&apos; ကက က</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="599"/> <location filename="../ui/controllers/installController.cpp" line="575"/>
<source>%1 has been removed from the server &apos;%2&apos;</source> <source>%1 has been removed from the server &apos;%2&apos;</source>
<translation>%1 က &apos;%2&apos; က</translation> <translation>%1 က &apos;%2&apos; က</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="608"/> <location filename="../ui/controllers/installController.cpp" line="584"/>
<source>Api config removed</source> <source>Api config removed</source>
<translation>Api config ကက</translation> <translation>Api config ကက</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="630"/> <location filename="../ui/controllers/installController.cpp" line="606"/>
<source>%1 cached profile cleared</source> <source>%1 cached profile cleared</source>
<translation>ကက %1 က </translation> <translation>ကက %1 က </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="769"/> <location filename="../ui/controllers/installController.cpp" line="745"/>
<source>Please login as the user</source> <source>Please login as the user</source>
<translation> log in က</translation> <translation> log in က</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="797"/> <location filename="../ui/controllers/installController.cpp" line="773"/>
<source>Server added successfully</source> <source>Server added successfully</source>
<translation>က </translation> <translation>က </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="845"/> <location filename="../ui/controllers/installController.cpp" line="821"/>
<source>%1 installed successfully.</source> <source>%1 installed successfully.</source>
<translation>%1 က .</translation> <translation>%1 က .</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="877"/> <location filename="../ui/controllers/installController.cpp" line="855"/>
<source>API config reloaded</source> <source>API config reloaded</source>
<translation>API config က က</translation> <translation>API config က က</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="881"/> <location filename="../ui/controllers/installController.cpp" line="859"/>
<source>Successfully changed the country of connection to %1</source> <source>Successfully changed the country of connection to %1</source>
<translation>ကက %1 က</translation> <translation>ကက %1 က</translation>
</message> </message>
@ -2327,97 +2324,107 @@ Already installed containers were found on the server. All installed containers
<context> <context>
<name>PageSetupWizardConfigSource</name> <name>PageSetupWizardConfigSource</name>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="241"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="269"/>
<source>File with connection settings</source> <source>File with connection settings</source>
<translation>ကက</translation> <translation>ကက</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
<source>Connection</source> <source>Connection</source>
<translation>က</translation> <translation>က</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
<source>Settings</source> <source>Settings</source>
<translation type="unfinished">က</translation> <translation type="unfinished">က</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
<source>Enable logs</source> <source>Enable logs</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/>
<source>Support tag</source>
<translation type="unfinished">က tag</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
<source>Copied</source>
<translation type="unfinished">က</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="140"/>
<source>Insert the key, add a configuration file or scan the QR-code</source> <source>Insert the key, add a configuration file or scan the QR-code</source>
<translation>Key က က QR-ကက က</translation> <translation>Key က က QR-ကက က</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="122"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="150"/>
<source>Insert key</source> <source>Insert key</source>
<translation>Key က</translation> <translation>Key က</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="151"/>
<source>Insert</source> <source>Insert</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
<source>Continue</source> <source>Continue</source>
<translation>ကက</translation> <translation>ကက</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="161"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="189"/>
<source>Other connection options</source> <source>Other connection options</source>
<translation>က</translation> <translation>က</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="172"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="200"/>
<source>VPN by Amnezia</source> <source>VPN by Amnezia</source>
<translation>Amnezia VPN</translation> <translation>Amnezia VPN</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="173"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="201"/>
<source>Connect to classic paid and free VPN services from Amnezia</source> <source>Connect to classic paid and free VPN services from Amnezia</source>
<translation>Amnezia VPN က</translation> <translation>Amnezia VPN က</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="196"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
<source>Self-hosted VPN</source> <source>Self-hosted VPN</source>
<translation>က host VPN</translation> <translation>က host VPN</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="197"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="225"/>
<source>Configure Amnezia VPN on your own server</source> <source>Configure Amnezia VPN on your own server</source>
<translation>Amnezia VPN က က </translation> <translation>Amnezia VPN က က </translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="217"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="245"/>
<source>Restore from backup</source> <source>Restore from backup</source>
<translation> </translation> <translation> </translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="223"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="251"/>
<source>Open backup file</source> <source>Open backup file</source>
<translation>က </translation> <translation>က </translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="252"/>
<source>Backup files (*.backup)</source> <source>Backup files (*.backup)</source>
<translation> (*.backup)</translation> <translation> (*.backup)</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="249"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="277"/>
<source>Open config file</source> <source>Open config file</source>
<translation>config က</translation> <translation>config က</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
<source>QR code</source> <source>QR code</source>
<translation>QR-က</translation> <translation>QR-က</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="291"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="319"/>
<source>I have nothing</source> <source>I have nothing</source>
<translation>က</translation> <translation>က</translation>
</message> </message>
@ -2805,67 +2812,67 @@ Already installed containers were found on the server. All installed containers
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="817"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="814"/>
<source>Creation date: %1</source> <source>Creation date: %1</source>
<translation>က: %1</translation> <translation>က: %1</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="825"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="822"/>
<source>Latest handshake: %1</source> <source>Latest handshake: %1</source>
<translation>က handshake : %1</translation> <translation>က handshake : %1</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="833"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="830"/>
<source>Data received: %1</source> <source>Data received: %1</source>
<translation>က: %1</translation> <translation>က: %1</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="841"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="838"/>
<source>Data sent: %1</source> <source>Data sent: %1</source>
<translation>က: %1</translation> <translation>က: %1</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="849"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
<source>Allowed IPs: %1</source> <source>Allowed IPs: %1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="870"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
<source>Rename</source> <source>Rename</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="916"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
<source>Client name</source> <source>Client name</source>
<translation>က</translation> <translation>က</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="929"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
<source>Save</source> <source>Save</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="963"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
<source>Revoke</source> <source>Revoke</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
<source>Revoke the config for a user - %1?</source> <source>Revoke the config for a user - %1?</source>
<translation> %1 က config က ?</translation> <translation> %1 က config က ?</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="968"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
<source>The user will no longer be able to connect to your server.</source> <source>The user will no longer be able to connect to your server.</source>
<translation> က.</translation> <translation> က.</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="969"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
<source>Continue</source> <source>Continue</source>
<translation>ကက</translation> <translation>ကက</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="970"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
<source>Cancel</source> <source>Cancel</source>
<translation>က</translation> <translation>က</translation>
</message> </message>
@ -2952,17 +2959,17 @@ Already installed containers were found on the server. All installed containers
<context> <context>
<name>PageStart</name> <name>PageStart</name>
<message> <message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="198"/> <location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
<source>Logging was disabled after 14 days, log files were deleted</source> <source>Logging was disabled after 14 days, log files were deleted</source>
<translation> ကက Logging က က ကက</translation> <translation> ကက Logging က က ကက</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/> <location filename="../ui/qml/Pages2/PageStart.qml" line="206"/>
<source>Settings restored from backup file</source> <source>Settings restored from backup file</source>
<translation>ကက </translation> <translation>ကက </translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="208"/> <location filename="../ui/qml/Pages2/PageStart.qml" line="212"/>
<source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source> <source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -3294,17 +3301,17 @@ Already installed containers were found on the server. All installed containers
<translation>Config ကက က က </translation> <translation>Config ကက က က </translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="58"/> <location filename="../core/errorstrings.cpp" line="59"/>
<source>Error when retrieving configuration from API</source> <source>Error when retrieving configuration from API</source>
<translation>API က </translation> <translation>API က </translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="59"/> <location filename="../core/errorstrings.cpp" line="60"/>
<source>This config has already been added to the application</source> <source>This config has already been added to the application</source>
<translation> config က က </translation> <translation> config က က </translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="78"/> <location filename="../core/errorstrings.cpp" line="80"/>
<source>ErrorCode: %1. </source> <source>ErrorCode: %1. </source>
<translation>က: %1. </translation> <translation>က: %1. </translation>
</message> </message>
@ -3374,62 +3381,72 @@ Already installed containers were found on the server. All installed containers
<translation>VPN pool မှု: ရရှိနိုင်သ</translation> <translation>VPN pool မှု: ရရှိနိုင်သ</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="55"/> <location filename="../core/errorstrings.cpp" line="53"/>
<source>Unable to open config file</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="56"/>
<source>VPN connection error</source> <source>VPN connection error</source>
<translation>VPN က</translation> <translation>VPN က</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="60"/> <location filename="../core/errorstrings.cpp" line="61"/>
<source>In the response from the server, an empty config was received</source> <source>In the response from the server, an empty config was received</source>
<translation> config က က</translation> <translation> config က က</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="61"/> <location filename="../core/errorstrings.cpp" line="62"/>
<source>SSL error occurred</source> <source>SSL error occurred</source>
<translation>SSL </translation> <translation>SSL </translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="62"/> <location filename="../core/errorstrings.cpp" line="63"/>
<source>Server response timeout on api request</source> <source>Server response timeout on api request</source>
<translation>Api က</translation> <translation>Api က</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="63"/> <location filename="../core/errorstrings.cpp" line="64"/>
<source>Missing AGW public key</source> <source>Missing AGW public key</source>
<translation>AGW public key က</translation> <translation>AGW public key က</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="66"/> <location filename="../core/errorstrings.cpp" line="65"/>
<source>Failed to decrypt response payload</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="68"/>
<source>QFile error: The file could not be opened</source> <source>QFile error: The file could not be opened</source>
<translation>QFile မှု: ဖိုင်ကို </translation> <translation>QFile မှု: ဖိုင်ကို </translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="67"/> <location filename="../core/errorstrings.cpp" line="69"/>
<source>QFile error: An error occurred when reading from the file</source> <source>QFile error: An error occurred when reading from the file</source>
<translation>QFile မှု: ဖိုင်ကိုဖတ်န </translation> <translation>QFile မှု: ဖိုင်ကိုဖတ်န </translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="68"/> <location filename="../core/errorstrings.cpp" line="70"/>
<source>QFile error: The file could not be accessed</source> <source>QFile error: The file could not be accessed</source>
<translation>QFile မှု: ဖိုင်ကို </translation> <translation>QFile မှု: ဖိုင်ကို </translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="69"/> <location filename="../core/errorstrings.cpp" line="71"/>
<source>QFile error: An unspecified error occurred</source> <source>QFile error: An unspecified error occurred</source>
<translation>QFile မှု: သတ်မှတ်မထ </translation> <translation>QFile မှု: သတ်မှတ်မထ </translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="70"/> <location filename="../core/errorstrings.cpp" line="72"/>
<source>QFile error: A fatal error occurred</source> <source>QFile error: A fatal error occurred</source>
<translation>QFile မှု: က </translation> <translation>QFile မှု: က </translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="71"/> <location filename="../core/errorstrings.cpp" line="73"/>
<source>QFile error: The operation was aborted</source> <source>QFile error: The operation was aborted</source>
<translation>QFile မှု: လုပ်ငန်က ကက</translation> <translation>QFile မှု: လုပ်ငန်က ကက</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="75"/> <location filename="../core/errorstrings.cpp" line="77"/>
<source>Internal error</source> <source>Internal error</source>
<translation>က </translation> <translation>က </translation>
</message> </message>
@ -4036,7 +4053,7 @@ For more detailed information, you can
<context> <context>
<name>VpnConnection</name> <name>VpnConnection</name>
<message> <message>
<location filename="../vpnconnection.cpp" line="408"/> <location filename="../vpnconnection.cpp" line="409"/>
<source>Mbps</source> <source>Mbps</source>
<translation>Mbps</translation> <translation>Mbps</translation>
</message> </message>

View file

@ -88,62 +88,62 @@
<context> <context>
<name>ConnectionController</name> <name>ConnectionController</name>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="214"/> <location filename="../ui/controllers/connectionController.cpp" line="217"/>
<source>VPN Protocols is not installed. <source>VPN Protocols is not installed.
Please install VPN container at first</source> Please install VPN container at first</source>
<translation>VPN-протоколы не установлены. <translation>VPN-протоколы не установлены.
Пожалуйста, установите протокол</translation> Пожалуйста, установите протокол</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="81"/> <location filename="../ui/controllers/connectionController.cpp" line="84"/>
<source>Connecting...</source> <source>Connecting...</source>
<translation>Подключение...</translation> <translation>Подключение...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="86"/> <location filename="../ui/controllers/connectionController.cpp" line="89"/>
<source>Connected</source> <source>Connected</source>
<translation>Подключено</translation> <translation>Подключено</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="110"/> <location filename="../ui/controllers/connectionController.cpp" line="113"/>
<source>Preparing...</source> <source>Preparing...</source>
<translation>Подготовка...</translation> <translation>Подготовка...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="132"/> <location filename="../ui/controllers/connectionController.cpp" line="135"/>
<source>Settings updated successfully, reconnnection...</source> <source>Settings updated successfully, reconnnection...</source>
<translation>Настройки успешно обновлены, переподключение...</translation> <translation>Настройки успешно обновлены, переподключение...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="135"/> <location filename="../ui/controllers/connectionController.cpp" line="138"/>
<source>Settings updated successfully</source> <source>Settings updated successfully</source>
<translation>Настройки успешно обновлены</translation> <translation>Настройки успешно обновлены</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="209"/> <location filename="../ui/controllers/connectionController.cpp" line="212"/>
<source>The selected protocol is not supported on the current platform</source> <source>The selected protocol is not supported on the current platform</source>
<translation>Выбранный протокол не поддерживается на данном устройстве</translation> <translation>Выбранный протокол не поддерживается на данном устройстве</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="233"/> <location filename="../ui/controllers/connectionController.cpp" line="236"/>
<source>unable to create configuration</source> <source>unable to create configuration</source>
<translation>не удалось создать конфигурацию</translation> <translation>не удалось создать конфигурацию</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="95"/> <location filename="../ui/controllers/connectionController.cpp" line="98"/>
<source>Reconnecting...</source> <source>Reconnecting...</source>
<translation>Переподключение...</translation> <translation>Переподключение...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.h" line="80"/> <location filename="../ui/controllers/connectionController.h" line="80"/>
<location filename="../ui/controllers/connectionController.cpp" line="100"/> <location filename="../ui/controllers/connectionController.cpp" line="103"/>
<location filename="../ui/controllers/connectionController.cpp" line="115"/> <location filename="../ui/controllers/connectionController.cpp" line="118"/>
<location filename="../ui/controllers/connectionController.cpp" line="121"/> <location filename="../ui/controllers/connectionController.cpp" line="124"/>
<source>Connect</source> <source>Connect</source>
<translation>Подключиться</translation> <translation>Подключиться</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="105"/> <location filename="../ui/controllers/connectionController.cpp" line="108"/>
<source>Disconnecting...</source> <source>Disconnecting...</source>
<translation>Отключение...</translation> <translation>Отключение...</translation>
</message> </message>
@ -258,23 +258,20 @@ Can&apos;t be disabled for current server</source>
<context> <context>
<name>ImportController</name> <name>ImportController</name>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="87"/>
<source>Unable to open file</source> <source>Unable to open file</source>
<translation>Невозможно открыть файл</translation> <translation type="vanished">Невозможно открыть файл</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="191"/>
<location filename="../ui/controllers/importController.cpp" line="196"/>
<source>Invalid configuration file</source> <source>Invalid configuration file</source>
<translation>Неверный файл конфигурации</translation> <translation type="vanished">Неверный файл конфигурации</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="622"/> <location filename="../ui/controllers/importController.cpp" line="623"/>
<source>Scanned %1 of %2.</source> <source>Scanned %1 of %2.</source>
<translation>Отсканировано %1 из %2.</translation> <translation>Отсканировано %1 из %2.</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="657"/> <location filename="../ui/controllers/importController.cpp" line="658"/>
<source>In the imported configuration, potentially dangerous lines were found:</source> <source>In the imported configuration, potentially dangerous lines were found:</source>
<translation>В импортированной конфигурации были обнаружены потенциально опасные строки:</translation> <translation>В импортированной конфигурации были обнаружены потенциально опасные строки:</translation>
</message> </message>
@ -282,86 +279,86 @@ Can&apos;t be disabled for current server</source>
<context> <context>
<name>InstallController</name> <name>InstallController</name>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="181"/> <location filename="../ui/controllers/installController.cpp" line="157"/>
<source>%1 installed successfully. </source> <source>%1 installed successfully. </source>
<translation>%1 успешно установлен. </translation> <translation>%1 успешно установлен. </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="183"/> <location filename="../ui/controllers/installController.cpp" line="159"/>
<source>%1 is already installed on the server. </source> <source>%1 is already installed on the server. </source>
<translation>%1 уже установлен на сервер. </translation> <translation>%1 уже установлен на сервер. </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="203"/> <location filename="../ui/controllers/installController.cpp" line="179"/>
<source> <source>
Added containers that were already installed on the server</source> Added containers that were already installed on the server</source>
<translation> <translation>
Добавлены сервисы и протоколы, которые были ранее установлены на сервер</translation> Добавлены сервисы и протоколы, которые были ранее установлены на сервер</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="283"/> <location filename="../ui/controllers/installController.cpp" line="259"/>
<source> <source>
Already installed containers were found on the server. All installed containers have been added to the application</source> Already installed containers were found on the server. All installed containers have been added to the application</source>
<translation> <translation>
На сервере обнаружены установленные протоколы и сервисы. Все они были добавлены в приложение</translation> На сервере обнаружены установленные протоколы и сервисы. Все они были добавлены в приложение</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="541"/> <location filename="../ui/controllers/installController.cpp" line="517"/>
<source>Settings updated successfully</source> <source>Settings updated successfully</source>
<translation>Настройки успешно обновлены</translation> <translation>Настройки успешно обновлены</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="558"/> <location filename="../ui/controllers/installController.cpp" line="534"/>
<source>Server &apos;%1&apos; was rebooted</source> <source>Server &apos;%1&apos; was rebooted</source>
<translation>Сервер &apos;%1&apos; был перезагружен</translation> <translation>Сервер &apos;%1&apos; был перезагружен</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="570"/> <location filename="../ui/controllers/installController.cpp" line="546"/>
<source>Server &apos;%1&apos; was removed</source> <source>Server &apos;%1&apos; was removed</source>
<translation>Сервер &apos;%1&apos; был удален</translation> <translation>Сервер &apos;%1&apos; был удален</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="581"/> <location filename="../ui/controllers/installController.cpp" line="557"/>
<source>All containers from server &apos;%1&apos; have been removed</source> <source>All containers from server &apos;%1&apos; have been removed</source>
<translation>Все протоколы и сервисы были удалены с сервера &apos;%1&apos;</translation> <translation>Все протоколы и сервисы были удалены с сервера &apos;%1&apos;</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="599"/> <location filename="../ui/controllers/installController.cpp" line="575"/>
<source>%1 has been removed from the server &apos;%2&apos;</source> <source>%1 has been removed from the server &apos;%2&apos;</source>
<translation>%1 был удален с сервера &apos;%2&apos;</translation> <translation>%1 был удален с сервера &apos;%2&apos;</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="608"/> <location filename="../ui/controllers/installController.cpp" line="584"/>
<source>Api config removed</source> <source>Api config removed</source>
<translation>Конфигурация API удалена</translation> <translation>Конфигурация API удалена</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="630"/> <location filename="../ui/controllers/installController.cpp" line="606"/>
<source>%1 cached profile cleared</source> <source>%1 cached profile cleared</source>
<translation>%1 закэшированный профиль очищен</translation> <translation>%1 закэшированный профиль очищен</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="769"/> <location filename="../ui/controllers/installController.cpp" line="745"/>
<source>Please login as the user</source> <source>Please login as the user</source>
<translation>Пожалуйста, войдите в систему от имени пользователя</translation> <translation>Пожалуйста, войдите в систему от имени пользователя</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="797"/> <location filename="../ui/controllers/installController.cpp" line="773"/>
<source>Server added successfully</source> <source>Server added successfully</source>
<translation>Сервер успешно добавлен</translation> <translation>Сервер успешно добавлен</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="845"/> <location filename="../ui/controllers/installController.cpp" line="821"/>
<source>%1 installed successfully.</source> <source>%1 installed successfully.</source>
<translation>%1 успешно установлен.</translation> <translation>%1 успешно установлен.</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="877"/> <location filename="../ui/controllers/installController.cpp" line="855"/>
<source>API config reloaded</source> <source>API config reloaded</source>
<translation>Конфигурация API перезагружена</translation> <translation>Конфигурация API перезагружена</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="881"/> <location filename="../ui/controllers/installController.cpp" line="859"/>
<source>Successfully changed the country of connection to %1</source> <source>Successfully changed the country of connection to %1</source>
<translation>Изменение страны подключения на %1</translation> <translation>Изменение страны подключения на %1</translation>
</message> </message>
@ -2505,7 +2502,7 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<translation type="vanished">Что у вас есть?</translation> <translation type="vanished">Что у вас есть?</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="241"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="269"/>
<source>File with connection settings</source> <source>File with connection settings</source>
<translation>Файл с настройками подключения</translation> <translation>Файл с настройками подключения</translation>
</message> </message>
@ -2514,92 +2511,102 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<translation type="vanished">Файл с настройками подключения или резервной копией</translation> <translation type="vanished">Файл с настройками подключения или резервной копией</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
<source>Connection</source> <source>Connection</source>
<translation>Соединение</translation> <translation>Соединение</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
<source>Settings</source> <source>Settings</source>
<translation type="unfinished">Настройки</translation> <translation type="unfinished">Настройки</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
<source>Enable logs</source> <source>Enable logs</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/>
<source>Support tag</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
<source>Copied</source>
<translation type="unfinished">Скопировано</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="140"/>
<source>Insert the key, add a configuration file or scan the QR-code</source> <source>Insert the key, add a configuration file or scan the QR-code</source>
<translation>Вставьте ключ, добавьте файл конфигурации или отсканируйте QR-код</translation> <translation>Вставьте ключ, добавьте файл конфигурации или отсканируйте QR-код</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="122"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="150"/>
<source>Insert key</source> <source>Insert key</source>
<translation>Вставьте ключ</translation> <translation>Вставьте ключ</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="151"/>
<source>Insert</source> <source>Insert</source>
<translation>Вставить</translation> <translation>Вставить</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
<source>Continue</source> <source>Continue</source>
<translation>Продолжить</translation> <translation>Продолжить</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="161"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="189"/>
<source>Other connection options</source> <source>Other connection options</source>
<translation>Другие варианты подключения</translation> <translation>Другие варианты подключения</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="172"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="200"/>
<source>VPN by Amnezia</source> <source>VPN by Amnezia</source>
<translation>VPN от Amnezia</translation> <translation>VPN от Amnezia</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="173"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="201"/>
<source>Connect to classic paid and free VPN services from Amnezia</source> <source>Connect to classic paid and free VPN services from Amnezia</source>
<translation>Подключайтесь к классическим платным и бесплатным VPN-сервисам от Amnezia</translation> <translation>Подключайтесь к классическим платным и бесплатным VPN-сервисам от Amnezia</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="196"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
<source>Self-hosted VPN</source> <source>Self-hosted VPN</source>
<translation>Self-hosted VPN</translation> <translation>Self-hosted VPN</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="197"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="225"/>
<source>Configure Amnezia VPN on your own server</source> <source>Configure Amnezia VPN on your own server</source>
<translation>Настроить VPN на собственном сервере</translation> <translation>Настроить VPN на собственном сервере</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="217"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="245"/>
<source>Restore from backup</source> <source>Restore from backup</source>
<translation>Восстановить из резервной копии</translation> <translation>Восстановить из резервной копии</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="223"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="251"/>
<source>Open backup file</source> <source>Open backup file</source>
<translation>Открыть резервную копию</translation> <translation>Открыть резервную копию</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="252"/>
<source>Backup files (*.backup)</source> <source>Backup files (*.backup)</source>
<translation>Файлы резервных копий (*.backup)</translation> <translation>Файлы резервных копий (*.backup)</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="249"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="277"/>
<source>Open config file</source> <source>Open config file</source>
<translation>Открыть файл с конфигурацией</translation> <translation>Открыть файл с конфигурацией</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
<source>QR code</source> <source>QR code</source>
<translation>QR-код</translation> <translation>QR-код</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="291"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="319"/>
<source>I have nothing</source> <source>I have nothing</source>
<translation>У меня ничего нет</translation> <translation>У меня ничего нет</translation>
</message> </message>
@ -3068,27 +3075,27 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation>Поиск</translation> <translation>Поиск</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="817"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="814"/>
<source>Creation date: %1</source> <source>Creation date: %1</source>
<translation>Дата создания: %1</translation> <translation>Дата создания: %1</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="825"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="822"/>
<source>Latest handshake: %1</source> <source>Latest handshake: %1</source>
<translation>Последнее рукопожатие: %1</translation> <translation>Последнее рукопожатие: %1</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="833"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="830"/>
<source>Data received: %1</source> <source>Data received: %1</source>
<translation>Получено данных: %1</translation> <translation>Получено данных: %1</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="841"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="838"/>
<source>Data sent: %1</source> <source>Data sent: %1</source>
<translation>Отправлено данных: %1</translation> <translation>Отправлено данных: %1</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="849"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
<source>Allowed IPs: %1</source> <source>Allowed IPs: %1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -3097,42 +3104,42 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation type="vanished">Дата создания: </translation> <translation type="vanished">Дата создания: </translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="870"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
<source>Rename</source> <source>Rename</source>
<translation>Переименовать</translation> <translation>Переименовать</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="916"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
<source>Client name</source> <source>Client name</source>
<translation>Имя клиента</translation> <translation>Имя клиента</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="929"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
<source>Save</source> <source>Save</source>
<translation>Сохранить</translation> <translation>Сохранить</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="963"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
<source>Revoke</source> <source>Revoke</source>
<translation>Отозвать</translation> <translation>Отозвать</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
<source>Revoke the config for a user - %1?</source> <source>Revoke the config for a user - %1?</source>
<translation>Отозвать конфигурацию для пользователя - %1?</translation> <translation>Отозвать конфигурацию для пользователя - %1?</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="968"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
<source>The user will no longer be able to connect to your server.</source> <source>The user will no longer be able to connect to your server.</source>
<translation>Пользователь больше не сможет подключаться к вашему серверу.</translation> <translation>Пользователь больше не сможет подключаться к вашему серверу.</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="969"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
<source>Continue</source> <source>Continue</source>
<translation>Продолжить</translation> <translation>Продолжить</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="970"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
<source>Cancel</source> <source>Cancel</source>
<translation>Отменить</translation> <translation>Отменить</translation>
</message> </message>
@ -3223,17 +3230,17 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<context> <context>
<name>PageStart</name> <name>PageStart</name>
<message> <message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="198"/> <location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
<source>Logging was disabled after 14 days, log files were deleted</source> <source>Logging was disabled after 14 days, log files were deleted</source>
<translation>Логирование было отключено по прошествии 14 дней, файлы логов были удалены.</translation> <translation>Логирование было отключено по прошествии 14 дней, файлы логов были удалены.</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/> <location filename="../ui/qml/Pages2/PageStart.qml" line="206"/>
<source>Settings restored from backup file</source> <source>Settings restored from backup file</source>
<translation>Настройки восстановлены из бэкап файла</translation> <translation>Настройки восстановлены из бэкап файла</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="208"/> <location filename="../ui/qml/Pages2/PageStart.qml" line="212"/>
<source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source> <source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -3630,17 +3637,17 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation>Конфигурация не содержит каких-либо контейнеров и учетных данных для подключения к серверу</translation> <translation>Конфигурация не содержит каких-либо контейнеров и учетных данных для подключения к серверу</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="58"/> <location filename="../core/errorstrings.cpp" line="59"/>
<source>Error when retrieving configuration from API</source> <source>Error when retrieving configuration from API</source>
<translation>Ошибка при получении конфигурации из API</translation> <translation>Ошибка при получении конфигурации из API</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="59"/> <location filename="../core/errorstrings.cpp" line="60"/>
<source>This config has already been added to the application</source> <source>This config has already been added to the application</source>
<translation>Данная конфигурация уже была добавлена в приложение</translation> <translation>Данная конфигурация уже была добавлена в приложение</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="78"/> <location filename="../core/errorstrings.cpp" line="80"/>
<source>ErrorCode: %1. </source> <source>ErrorCode: %1. </source>
<translation>Код ошибки: %1. </translation> <translation>Код ошибки: %1. </translation>
</message> </message>
@ -3699,62 +3706,72 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation>Ошибка пула VPN: нет доступных адресов</translation> <translation>Ошибка пула VPN: нет доступных адресов</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="55"/> <location filename="../core/errorstrings.cpp" line="53"/>
<source>Unable to open config file</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="56"/>
<source>VPN connection error</source> <source>VPN connection error</source>
<translation>Ошибка VPN-соединения</translation> <translation>Ошибка VPN-соединения</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="60"/> <location filename="../core/errorstrings.cpp" line="61"/>
<source>In the response from the server, an empty config was received</source> <source>In the response from the server, an empty config was received</source>
<translation>В ответе от сервера была получена пустая конфигурация</translation> <translation>В ответе от сервера была получена пустая конфигурация</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="61"/> <location filename="../core/errorstrings.cpp" line="62"/>
<source>SSL error occurred</source> <source>SSL error occurred</source>
<translation>Произошла ошибка SSL</translation> <translation>Произошла ошибка SSL</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="62"/> <location filename="../core/errorstrings.cpp" line="63"/>
<source>Server response timeout on api request</source> <source>Server response timeout on api request</source>
<translation>Тайм-аут ответа сервера на запрос API</translation> <translation>Тайм-аут ответа сервера на запрос API</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="63"/> <location filename="../core/errorstrings.cpp" line="64"/>
<source>Missing AGW public key</source> <source>Missing AGW public key</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="66"/> <location filename="../core/errorstrings.cpp" line="65"/>
<source>Failed to decrypt response payload</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="68"/>
<source>QFile error: The file could not be opened</source> <source>QFile error: The file could not be opened</source>
<translation>Ошибка QFile: не удалось открыть файл</translation> <translation>Ошибка QFile: не удалось открыть файл</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="67"/> <location filename="../core/errorstrings.cpp" line="69"/>
<source>QFile error: An error occurred when reading from the file</source> <source>QFile error: An error occurred when reading from the file</source>
<translation>Ошибка QFile: произошла ошибка при чтении из файла</translation> <translation>Ошибка QFile: произошла ошибка при чтении из файла</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="68"/> <location filename="../core/errorstrings.cpp" line="70"/>
<source>QFile error: The file could not be accessed</source> <source>QFile error: The file could not be accessed</source>
<translation>Ошибка QFile: не удалось получить доступ к файлу</translation> <translation>Ошибка QFile: не удалось получить доступ к файлу</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="69"/> <location filename="../core/errorstrings.cpp" line="71"/>
<source>QFile error: An unspecified error occurred</source> <source>QFile error: An unspecified error occurred</source>
<translation>Ошибка QFile: произошла неизвестная ошибка</translation> <translation>Ошибка QFile: произошла неизвестная ошибка</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="70"/> <location filename="../core/errorstrings.cpp" line="72"/>
<source>QFile error: A fatal error occurred</source> <source>QFile error: A fatal error occurred</source>
<translation>Ошибка QFile: произошла фатальная ошибка</translation> <translation>Ошибка QFile: произошла фатальная ошибка</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="71"/> <location filename="../core/errorstrings.cpp" line="73"/>
<source>QFile error: The operation was aborted</source> <source>QFile error: The operation was aborted</source>
<translation>Ошибка QFile: операция была прервана</translation> <translation>Ошибка QFile: операция была прервана</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="75"/> <location filename="../core/errorstrings.cpp" line="77"/>
<source>Internal error</source> <source>Internal error</source>
<translation>Внутренняя ошибка</translation> <translation>Внутренняя ошибка</translation>
</message> </message>
@ -4454,7 +4471,7 @@ This means that AmneziaWG keeps the fast performance of the original while addin
<context> <context>
<name>VpnConnection</name> <name>VpnConnection</name>
<message> <message>
<location filename="../vpnconnection.cpp" line="408"/> <location filename="../vpnconnection.cpp" line="409"/>
<source>Mbps</source> <source>Mbps</source>
<translation>Мбит/с</translation> <translation>Мбит/с</translation>
</message> </message>

View file

@ -111,62 +111,62 @@
<context> <context>
<name>ConnectionController</name> <name>ConnectionController</name>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="214"/> <location filename="../ui/controllers/connectionController.cpp" line="217"/>
<source>VPN Protocols is not installed. <source>VPN Protocols is not installed.
Please install VPN container at first</source> Please install VPN container at first</source>
<translation>VPN протоколи не встановлено. <translation>VPN протоколи не встановлено.
Будь-ласка, встановіть VPN контейнер</translation> Будь-ласка, встановіть VPN контейнер</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="233"/> <location filename="../ui/controllers/connectionController.cpp" line="236"/>
<source>unable to create configuration</source> <source>unable to create configuration</source>
<translation>Неможливо створити конфігурацію</translation> <translation>Неможливо створити конфігурацію</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="81"/> <location filename="../ui/controllers/connectionController.cpp" line="84"/>
<source>Connecting...</source> <source>Connecting...</source>
<translation>Підключення...</translation> <translation>Підключення...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="86"/> <location filename="../ui/controllers/connectionController.cpp" line="89"/>
<source>Connected</source> <source>Connected</source>
<translation>Підключено</translation> <translation>Підключено</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="110"/> <location filename="../ui/controllers/connectionController.cpp" line="113"/>
<source>Preparing...</source> <source>Preparing...</source>
<translation>Підготовка...</translation> <translation>Підготовка...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="132"/> <location filename="../ui/controllers/connectionController.cpp" line="135"/>
<source>Settings updated successfully, reconnnection...</source> <source>Settings updated successfully, reconnnection...</source>
<translation>Налаштування оновлено, підключення...</translation> <translation>Налаштування оновлено, підключення...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="135"/> <location filename="../ui/controllers/connectionController.cpp" line="138"/>
<source>Settings updated successfully</source> <source>Settings updated successfully</source>
<translation>Налаштування оновлено</translation> <translation>Налаштування оновлено</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="209"/> <location filename="../ui/controllers/connectionController.cpp" line="212"/>
<source>The selected protocol is not supported on the current platform</source> <source>The selected protocol is not supported on the current platform</source>
<translation>Вибраний протокол не підтримується на цьому пристрої</translation> <translation>Вибраний протокол не підтримується на цьому пристрої</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="95"/> <location filename="../ui/controllers/connectionController.cpp" line="98"/>
<source>Reconnecting...</source> <source>Reconnecting...</source>
<translation>Перепідключення...</translation> <translation>Перепідключення...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.h" line="80"/> <location filename="../ui/controllers/connectionController.h" line="80"/>
<location filename="../ui/controllers/connectionController.cpp" line="100"/> <location filename="../ui/controllers/connectionController.cpp" line="103"/>
<location filename="../ui/controllers/connectionController.cpp" line="115"/> <location filename="../ui/controllers/connectionController.cpp" line="118"/>
<location filename="../ui/controllers/connectionController.cpp" line="121"/> <location filename="../ui/controllers/connectionController.cpp" line="124"/>
<source>Connect</source> <source>Connect</source>
<translation>Підключитись</translation> <translation>Підключитись</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="105"/> <location filename="../ui/controllers/connectionController.cpp" line="108"/>
<source>Disconnecting...</source> <source>Disconnecting...</source>
<translation>Відключаємось...</translation> <translation>Відключаємось...</translation>
</message> </message>
@ -285,23 +285,20 @@ Can&apos;t be disabled for current server</source>
<context> <context>
<name>ImportController</name> <name>ImportController</name>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="87"/>
<source>Unable to open file</source> <source>Unable to open file</source>
<translation>Неможливо відкрити файл</translation> <translation type="vanished">Неможливо відкрити файл</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="191"/>
<location filename="../ui/controllers/importController.cpp" line="196"/>
<source>Invalid configuration file</source> <source>Invalid configuration file</source>
<translation>Недійсний файл конфігурації</translation> <translation type="vanished">Недійсний файл конфігурації</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="622"/> <location filename="../ui/controllers/importController.cpp" line="623"/>
<source>Scanned %1 of %2.</source> <source>Scanned %1 of %2.</source>
<translation>Відскановано %1 з %2.</translation> <translation>Відскановано %1 з %2.</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="657"/> <location filename="../ui/controllers/importController.cpp" line="658"/>
<source>In the imported configuration, potentially dangerous lines were found:</source> <source>In the imported configuration, potentially dangerous lines were found:</source>
<translation>У імпортованій конфігурації знайдено потенційно небезпечні рядки:</translation> <translation>У імпортованій конфігурації знайдено потенційно небезпечні рядки:</translation>
</message> </message>
@ -309,85 +306,85 @@ Can&apos;t be disabled for current server</source>
<context> <context>
<name>InstallController</name> <name>InstallController</name>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="181"/> <location filename="../ui/controllers/installController.cpp" line="157"/>
<source>%1 installed successfully. </source> <source>%1 installed successfully. </source>
<translation>%1 встановлено. </translation> <translation>%1 встановлено. </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="183"/> <location filename="../ui/controllers/installController.cpp" line="159"/>
<source>%1 is already installed on the server. </source> <source>%1 is already installed on the server. </source>
<translation>%1 вже встановлено на сервері. </translation> <translation>%1 вже встановлено на сервері. </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="203"/> <location filename="../ui/controllers/installController.cpp" line="179"/>
<source> <source>
Added containers that were already installed on the server</source> Added containers that were already installed on the server</source>
<translation>Додані сервіси і протоколи, які були раніше встановлені на сервері</translation> <translation>Додані сервіси і протоколи, які були раніше встановлені на сервері</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="283"/> <location filename="../ui/controllers/installController.cpp" line="259"/>
<source> <source>
Already installed containers were found on the server. All installed containers have been added to the application</source> Already installed containers were found on the server. All installed containers have been added to the application</source>
<translation> <translation>
На сервері знайдені сервіси та протоколи, всі вони додані в застосунок</translation> На сервері знайдені сервіси та протоколи, всі вони додані в застосунок</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="541"/> <location filename="../ui/controllers/installController.cpp" line="517"/>
<source>Settings updated successfully</source> <source>Settings updated successfully</source>
<translation>Налаштування оновлено</translation> <translation>Налаштування оновлено</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="558"/> <location filename="../ui/controllers/installController.cpp" line="534"/>
<source>Server &apos;%1&apos; was rebooted</source> <source>Server &apos;%1&apos; was rebooted</source>
<translation>Сервер &apos;%1&apos; перезавантажено</translation> <translation>Сервер &apos;%1&apos; перезавантажено</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="570"/> <location filename="../ui/controllers/installController.cpp" line="546"/>
<source>Server &apos;%1&apos; was removed</source> <source>Server &apos;%1&apos; was removed</source>
<translation>Сервер &apos;%1&apos; був видалений</translation> <translation>Сервер &apos;%1&apos; був видалений</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="581"/> <location filename="../ui/controllers/installController.cpp" line="557"/>
<source>All containers from server &apos;%1&apos; have been removed</source> <source>All containers from server &apos;%1&apos; have been removed</source>
<translation>Всі сервіси та протоколи були видалені з сервера &apos;%1&apos;</translation> <translation>Всі сервіси та протоколи були видалені з сервера &apos;%1&apos;</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="599"/> <location filename="../ui/controllers/installController.cpp" line="575"/>
<source>%1 has been removed from the server &apos;%2&apos;</source> <source>%1 has been removed from the server &apos;%2&apos;</source>
<translation>%1 був видалений з сервера &apos;%2&apos;</translation> <translation>%1 був видалений з сервера &apos;%2&apos;</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="608"/> <location filename="../ui/controllers/installController.cpp" line="584"/>
<source>Api config removed</source> <source>Api config removed</source>
<translation>Конфігурацію API видалено</translation> <translation>Конфігурацію API видалено</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="630"/> <location filename="../ui/controllers/installController.cpp" line="606"/>
<source>%1 cached profile cleared</source> <source>%1 cached profile cleared</source>
<translation>Кешований профіль %1 очищено</translation> <translation>Кешований профіль %1 очищено</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="769"/> <location filename="../ui/controllers/installController.cpp" line="745"/>
<source>Please login as the user</source> <source>Please login as the user</source>
<translation>Буль-ласка, увійдіть в систему від імені користувача</translation> <translation>Буль-ласка, увійдіть в систему від імені користувача</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="797"/> <location filename="../ui/controllers/installController.cpp" line="773"/>
<source>Server added successfully</source> <source>Server added successfully</source>
<translation>Сервер додано</translation> <translation>Сервер додано</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="845"/> <location filename="../ui/controllers/installController.cpp" line="821"/>
<source>%1 installed successfully.</source> <source>%1 installed successfully.</source>
<translation>%1 встановлено успішно.</translation> <translation>%1 встановлено успішно.</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="877"/> <location filename="../ui/controllers/installController.cpp" line="855"/>
<source>API config reloaded</source> <source>API config reloaded</source>
<translation>Конфігурацію API перезавантажено</translation> <translation>Конфігурацію API перезавантажено</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="881"/> <location filename="../ui/controllers/installController.cpp" line="859"/>
<source>Successfully changed the country of connection to %1</source> <source>Successfully changed the country of connection to %1</source>
<translation>Успішно змінено країну підключення на %1</translation> <translation>Успішно змінено країну підключення на %1</translation>
</message> </message>
@ -2591,7 +2588,7 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<translation type="vanished">Виберіть що у вас є</translation> <translation type="vanished">Виберіть що у вас є</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="241"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="269"/>
<source>File with connection settings</source> <source>File with connection settings</source>
<translation>Файл з налаштуваннями підключення</translation> <translation>Файл з налаштуваннями підключення</translation>
</message> </message>
@ -2600,92 +2597,102 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<translation type="vanished">Файл з налаштуваннями підключення або бекап</translation> <translation type="vanished">Файл з налаштуваннями підключення або бекап</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
<source>Connection</source> <source>Connection</source>
<translation>Підключення</translation> <translation>Підключення</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
<source>Settings</source> <source>Settings</source>
<translation type="unfinished">Налаштування</translation> <translation type="unfinished">Налаштування</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
<source>Enable logs</source> <source>Enable logs</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/>
<source>Support tag</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
<source>Copied</source>
<translation type="unfinished">Скопійовано</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="140"/>
<source>Insert the key, add a configuration file or scan the QR-code</source> <source>Insert the key, add a configuration file or scan the QR-code</source>
<translation>Вставте ключ, додайте файл конфігурації або відскануйте QR-код</translation> <translation>Вставте ключ, додайте файл конфігурації або відскануйте QR-код</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="122"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="150"/>
<source>Insert key</source> <source>Insert key</source>
<translation>Вставити ключ</translation> <translation>Вставити ключ</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="151"/>
<source>Insert</source> <source>Insert</source>
<translation>Вставити</translation> <translation>Вставити</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
<source>Continue</source> <source>Continue</source>
<translation>Продовжити</translation> <translation>Продовжити</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="161"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="189"/>
<source>Other connection options</source> <source>Other connection options</source>
<translation>Інші параметри підключення</translation> <translation>Інші параметри підключення</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="172"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="200"/>
<source>VPN by Amnezia</source> <source>VPN by Amnezia</source>
<translation>VPN від Amnezia</translation> <translation>VPN від Amnezia</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="173"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="201"/>
<source>Connect to classic paid and free VPN services from Amnezia</source> <source>Connect to classic paid and free VPN services from Amnezia</source>
<translation>Підключайтеся до звичайних платних та безкоштовних VPN-сервісів від Amnezia</translation> <translation>Підключайтеся до звичайних платних та безкоштовних VPN-сервісів від Amnezia</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="196"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
<source>Self-hosted VPN</source> <source>Self-hosted VPN</source>
<translation>Self-hosted VPN</translation> <translation>Self-hosted VPN</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="197"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="225"/>
<source>Configure Amnezia VPN on your own server</source> <source>Configure Amnezia VPN on your own server</source>
<translation>Налаштуйте Amnezia VPN на власному сервері</translation> <translation>Налаштуйте Amnezia VPN на власному сервері</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="217"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="245"/>
<source>Restore from backup</source> <source>Restore from backup</source>
<translation>Відновити із бекапа</translation> <translation>Відновити із бекапа</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="223"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="251"/>
<source>Open backup file</source> <source>Open backup file</source>
<translation>Відкрити бекап файл</translation> <translation>Відкрити бекап файл</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="252"/>
<source>Backup files (*.backup)</source> <source>Backup files (*.backup)</source>
<translation>Файли резервної копії (*.backup)</translation> <translation>Файли резервної копії (*.backup)</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="249"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="277"/>
<source>Open config file</source> <source>Open config file</source>
<translation>Відкрити файл з конфігурацією</translation> <translation>Відкрити файл з конфігурацією</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
<source>QR code</source> <source>QR code</source>
<translation>QR-код</translation> <translation>QR-код</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="291"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="319"/>
<source>I have nothing</source> <source>I have nothing</source>
<translation>У мене нічого нема</translation> <translation>У мене нічого нема</translation>
</message> </message>
@ -3163,27 +3170,27 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation>Пошук</translation> <translation>Пошук</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="817"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="814"/>
<source>Creation date: %1</source> <source>Creation date: %1</source>
<translation>Дата створення: %1</translation> <translation>Дата створення: %1</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="825"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="822"/>
<source>Latest handshake: %1</source> <source>Latest handshake: %1</source>
<translation>Останнє з&apos;єднання: %1</translation> <translation>Останнє з&apos;єднання: %1</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="833"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="830"/>
<source>Data received: %1</source> <source>Data received: %1</source>
<translation>Отримано даних: %1</translation> <translation>Отримано даних: %1</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="841"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="838"/>
<source>Data sent: %1</source> <source>Data sent: %1</source>
<translation>Відправлено даних: %1</translation> <translation>Відправлено даних: %1</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="849"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
<source>Allowed IPs: %1</source> <source>Allowed IPs: %1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -3192,42 +3199,42 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation type="obsolete">Дата створення:</translation> <translation type="obsolete">Дата створення:</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="870"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
<source>Rename</source> <source>Rename</source>
<translation>Перейменувати</translation> <translation>Перейменувати</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="916"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
<source>Client name</source> <source>Client name</source>
<translation>Назва клієнта</translation> <translation>Назва клієнта</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="929"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
<source>Save</source> <source>Save</source>
<translation>Зберегти</translation> <translation>Зберегти</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="963"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
<source>Revoke</source> <source>Revoke</source>
<translation>Відкликати</translation> <translation>Відкликати</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
<source>Revoke the config for a user - %1?</source> <source>Revoke the config for a user - %1?</source>
<translation>Відкликати доступ для користувача - %1?</translation> <translation>Відкликати доступ для користувача - %1?</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="968"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
<source>The user will no longer be able to connect to your server.</source> <source>The user will no longer be able to connect to your server.</source>
<translation>Користувач більше не зможе підключатись до вашого сервера </translation> <translation>Користувач більше не зможе підключатись до вашого сервера </translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="969"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
<source>Continue</source> <source>Continue</source>
<translation>Продовжити</translation> <translation>Продовжити</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="970"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
<source>Cancel</source> <source>Cancel</source>
<translation>Відмінити</translation> <translation>Відмінити</translation>
</message> </message>
@ -3317,17 +3324,17 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<context> <context>
<name>PageStart</name> <name>PageStart</name>
<message> <message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="198"/> <location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
<source>Logging was disabled after 14 days, log files were deleted</source> <source>Logging was disabled after 14 days, log files were deleted</source>
<translation>Логування було вимкнене через 14 днів, файли журналів були видалені</translation> <translation>Логування було вимкнене через 14 днів, файли журналів були видалені</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/> <location filename="../ui/qml/Pages2/PageStart.qml" line="206"/>
<source>Settings restored from backup file</source> <source>Settings restored from backup file</source>
<translation>Відновлення налаштувань із бекап файлу</translation> <translation>Відновлення налаштувань із бекап файлу</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="208"/> <location filename="../ui/qml/Pages2/PageStart.qml" line="212"/>
<source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source> <source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -3726,17 +3733,17 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation type="unfinished">Конфігурація не містить контейнерів і облікових даних для підключення до серверу</translation> <translation type="unfinished">Конфігурація не містить контейнерів і облікових даних для підключення до серверу</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="58"/> <location filename="../core/errorstrings.cpp" line="59"/>
<source>Error when retrieving configuration from API</source> <source>Error when retrieving configuration from API</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="59"/> <location filename="../core/errorstrings.cpp" line="60"/>
<source>This config has already been added to the application</source> <source>This config has already been added to the application</source>
<translation>Ця конфігурація вже була додана в застосунок</translation> <translation>Ця конфігурація вже була додана в застосунок</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="78"/> <location filename="../core/errorstrings.cpp" line="80"/>
<source>ErrorCode: %1. </source> <source>ErrorCode: %1. </source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -3795,62 +3802,72 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation>VPN pool error: no available addresses</translation> <translation>VPN pool error: no available addresses</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="55"/> <location filename="../core/errorstrings.cpp" line="53"/>
<source>Unable to open config file</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="56"/>
<source>VPN connection error</source> <source>VPN connection error</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="60"/> <location filename="../core/errorstrings.cpp" line="61"/>
<source>In the response from the server, an empty config was received</source> <source>In the response from the server, an empty config was received</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="61"/> <location filename="../core/errorstrings.cpp" line="62"/>
<source>SSL error occurred</source> <source>SSL error occurred</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="62"/> <location filename="../core/errorstrings.cpp" line="63"/>
<source>Server response timeout on api request</source> <source>Server response timeout on api request</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="63"/> <location filename="../core/errorstrings.cpp" line="64"/>
<source>Missing AGW public key</source> <source>Missing AGW public key</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="66"/> <location filename="../core/errorstrings.cpp" line="65"/>
<source>QFile error: The file could not be opened</source> <source>Failed to decrypt response payload</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="67"/>
<source>QFile error: An error occurred when reading from the file</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="68"/> <location filename="../core/errorstrings.cpp" line="68"/>
<source>QFile error: The file could not be accessed</source> <source>QFile error: The file could not be opened</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="69"/> <location filename="../core/errorstrings.cpp" line="69"/>
<source>QFile error: An unspecified error occurred</source> <source>QFile error: An error occurred when reading from the file</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="70"/> <location filename="../core/errorstrings.cpp" line="70"/>
<source>QFile error: A fatal error occurred</source> <source>QFile error: The file could not be accessed</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="71"/> <location filename="../core/errorstrings.cpp" line="71"/>
<source>QFile error: An unspecified error occurred</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="72"/>
<source>QFile error: A fatal error occurred</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="73"/>
<source>QFile error: The operation was aborted</source> <source>QFile error: The operation was aborted</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="75"/> <location filename="../core/errorstrings.cpp" line="77"/>
<source>Internal error</source> <source>Internal error</source>
<translation>Internal error</translation> <translation>Internal error</translation>
</message> </message>
@ -4531,7 +4548,7 @@ This means that AmneziaWG keeps the fast performance of the original while addin
<context> <context>
<name>VpnConnection</name> <name>VpnConnection</name>
<message> <message>
<location filename="../vpnconnection.cpp" line="408"/> <location filename="../vpnconnection.cpp" line="409"/>
<source>Mbps</source> <source>Mbps</source>
<translation>Mbps</translation> <translation>Mbps</translation>
</message> </message>

View file

@ -89,60 +89,60 @@
<name>ConnectionController</name> <name>ConnectionController</name>
<message> <message>
<location filename="../ui/controllers/connectionController.h" line="80"/> <location filename="../ui/controllers/connectionController.h" line="80"/>
<location filename="../ui/controllers/connectionController.cpp" line="100"/> <location filename="../ui/controllers/connectionController.cpp" line="103"/>
<location filename="../ui/controllers/connectionController.cpp" line="115"/> <location filename="../ui/controllers/connectionController.cpp" line="118"/>
<location filename="../ui/controllers/connectionController.cpp" line="121"/> <location filename="../ui/controllers/connectionController.cpp" line="124"/>
<source>Connect</source> <source>Connect</source>
<translation>جوڑنا</translation> <translation>جوڑنا</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="209"/> <location filename="../ui/controllers/connectionController.cpp" line="212"/>
<source>The selected protocol is not supported on the current platform</source> <source>The selected protocol is not supported on the current platform</source>
<translation>منتخب کردہ پروٹوکول موجودہ پلیٹ فارم پر تعاون یافتہ نہیں ہے</translation> <translation>منتخب کردہ پروٹوکول موجودہ پلیٹ فارم پر تعاون یافتہ نہیں ہے</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="214"/> <location filename="../ui/controllers/connectionController.cpp" line="217"/>
<source>VPN Protocols is not installed. <source>VPN Protocols is not installed.
Please install VPN container at first</source> Please install VPN container at first</source>
<translation>وی پی این پروٹوکول انسٹال نہیں ہے,براہ کرم پہلےوی پی این کنٹینر انسٹال کریں</translation> <translation>وی پی این پروٹوکول انسٹال نہیں ہے,براہ کرم پہلےوی پی این کنٹینر انسٹال کریں</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="233"/> <location filename="../ui/controllers/connectionController.cpp" line="236"/>
<source>unable to create configuration</source> <source>unable to create configuration</source>
<translation>تشکیل تیار کرنے میں ناکام</translation> <translation>تشکیل تیار کرنے میں ناکام</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="81"/> <location filename="../ui/controllers/connectionController.cpp" line="84"/>
<source>Connecting...</source> <source>Connecting...</source>
<translation>جوڑاجارھاھے....</translation> <translation>جوڑاجارھاھے....</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="86"/> <location filename="../ui/controllers/connectionController.cpp" line="89"/>
<source>Connected</source> <source>Connected</source>
<translation>جوڑاجارھاھے</translation> <translation>جوڑاجارھاھے</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="95"/> <location filename="../ui/controllers/connectionController.cpp" line="98"/>
<source>Reconnecting...</source> <source>Reconnecting...</source>
<translation>دوبارہ جوڑنےکی کوشش...</translation> <translation>دوبارہ جوڑنےکی کوشش...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="105"/> <location filename="../ui/controllers/connectionController.cpp" line="108"/>
<source>Disconnecting...</source> <source>Disconnecting...</source>
<translation>منقطع کرنا...</translation> <translation>منقطع کرنا...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="110"/> <location filename="../ui/controllers/connectionController.cpp" line="113"/>
<source>Preparing...</source> <source>Preparing...</source>
<translation>تیاری کیا جا رہا ہے...</translation> <translation>تیاری کیا جا رہا ہے...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="132"/> <location filename="../ui/controllers/connectionController.cpp" line="135"/>
<source>Settings updated successfully, reconnnection...</source> <source>Settings updated successfully, reconnnection...</source>
<translation>ترتیب ک ھوگی،دوبارہ جوڑنےکی کوشش...</translation> <translation>ترتیب ک ھوگی،دوبارہ جوڑنےکی کوشش...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="135"/> <location filename="../ui/controllers/connectionController.cpp" line="138"/>
<source>Settings updated successfully</source> <source>Settings updated successfully</source>
<translation>دوبارہ ترتیب تاذہ کامیاب</translation> <translation>دوبارہ ترتیب تاذہ کامیاب</translation>
</message> </message>
@ -252,23 +252,20 @@ Can&apos;t be disabled for current server</source>
<context> <context>
<name>ImportController</name> <name>ImportController</name>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="87"/>
<source>Unable to open file</source> <source>Unable to open file</source>
<translation>فائل کو کھولنے سے قاصر ہے</translation> <translation type="vanished">فائل کو کھولنے سے قاصر ہے</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="191"/>
<location filename="../ui/controllers/importController.cpp" line="196"/>
<source>Invalid configuration file</source> <source>Invalid configuration file</source>
<translation>غلط کنفیگریشن فائل</translation> <translation type="vanished">غلط کنفیگریشن فائل</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="622"/> <location filename="../ui/controllers/importController.cpp" line="623"/>
<source>Scanned %1 of %2.</source> <source>Scanned %1 of %2.</source>
<translation>سکین%1 کی%2.</translation> <translation>سکین%1 کی%2.</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="657"/> <location filename="../ui/controllers/importController.cpp" line="658"/>
<source>In the imported configuration, potentially dangerous lines were found:</source> <source>In the imported configuration, potentially dangerous lines were found:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -276,86 +273,86 @@ Can&apos;t be disabled for current server</source>
<context> <context>
<name>InstallController</name> <name>InstallController</name>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="181"/> <location filename="../ui/controllers/installController.cpp" line="157"/>
<source>%1 installed successfully. </source> <source>%1 installed successfully. </source>
<translation>%1 کامیابی سےنصب. </translation> <translation>%1 کامیابی سےنصب. </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="183"/> <location filename="../ui/controllers/installController.cpp" line="159"/>
<source>%1 is already installed on the server. </source> <source>%1 is already installed on the server. </source>
<translation>%1 پہلے ہی سرور پر انسٹال ہے. </translation> <translation>%1 پہلے ہی سرور پر انسٹال ہے. </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="203"/> <location filename="../ui/controllers/installController.cpp" line="179"/>
<source> <source>
Added containers that were already installed on the server</source> Added containers that were already installed on the server</source>
<translation> <translation>
وہ کنٹینرز شامل کیے گئے جو پہلے سے سرور پر نصب تھے</translation> وہ کنٹینرز شامل کیے گئے جو پہلے سے سرور پر نصب تھے</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="283"/> <location filename="../ui/controllers/installController.cpp" line="259"/>
<source> <source>
Already installed containers were found on the server. All installed containers have been added to the application</source> Already installed containers were found on the server. All installed containers have been added to the application</source>
<translation> <translation>
سرور پر پہلے سے نصب کنٹینرز پائے گئے۔ تمام نصب کنٹینرز کو ایپلی کیشن میں شامل کر دیا گیا ہے</translation> سرور پر پہلے سے نصب کنٹینرز پائے گئے۔ تمام نصب کنٹینرز کو ایپلی کیشن میں شامل کر دیا گیا ہے</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="541"/> <location filename="../ui/controllers/installController.cpp" line="517"/>
<source>Settings updated successfully</source> <source>Settings updated successfully</source>
<translation>ترتیب کامیابی کے ساتھ اپ ڈیٹ ہو گئی</translation> <translation>ترتیب کامیابی کے ساتھ اپ ڈیٹ ہو گئی</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="558"/> <location filename="../ui/controllers/installController.cpp" line="534"/>
<source>Server &apos;%1&apos; was rebooted</source> <source>Server &apos;%1&apos; was rebooted</source>
<translation>سرور %1 دوبارہ چالو کیا گیا تھا</translation> <translation>سرور %1 دوبارہ چالو کیا گیا تھا</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="570"/> <location filename="../ui/controllers/installController.cpp" line="546"/>
<source>Server &apos;%1&apos; was removed</source> <source>Server &apos;%1&apos; was removed</source>
<translation>سرور %1 ہٹا دیا گیا تھا</translation> <translation>سرور %1 ہٹا دیا گیا تھا</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="581"/> <location filename="../ui/controllers/installController.cpp" line="557"/>
<source>All containers from server &apos;%1&apos; have been removed</source> <source>All containers from server &apos;%1&apos; have been removed</source>
<translation>سرور &apos;%1&apos; سے تمام کنٹینرز ہٹا دیے گئے ہیں</translation> <translation>سرور &apos;%1&apos; سے تمام کنٹینرز ہٹا دیے گئے ہیں</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="599"/> <location filename="../ui/controllers/installController.cpp" line="575"/>
<source>%1 has been removed from the server &apos;%2&apos;</source> <source>%1 has been removed from the server &apos;%2&apos;</source>
<translation>سرور &apos;%2&apos; سے %1 ہٹا دیا گیا ہے</translation> <translation>سرور &apos;%2&apos; سے %1 ہٹا دیا گیا ہے</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="608"/> <location filename="../ui/controllers/installController.cpp" line="584"/>
<source>Api config removed</source> <source>Api config removed</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="630"/> <location filename="../ui/controllers/installController.cpp" line="606"/>
<source>%1 cached profile cleared</source> <source>%1 cached profile cleared</source>
<translation>%1 کیش کردہ پروفائل ختم کر دی گئی</translation> <translation>%1 کیش کردہ پروفائل ختم کر دی گئی</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="769"/> <location filename="../ui/controllers/installController.cpp" line="745"/>
<source>Please login as the user</source> <source>Please login as the user</source>
<translation>براہ کرم صارف کے طور پر لاگ ان کریں</translation> <translation>براہ کرم صارف کے طور پر لاگ ان کریں</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="797"/> <location filename="../ui/controllers/installController.cpp" line="773"/>
<source>Server added successfully</source> <source>Server added successfully</source>
<translation>سرور کامیابی سے شامل کیا گیا</translation> <translation>سرور کامیابی سے شامل کیا گیا</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="845"/> <location filename="../ui/controllers/installController.cpp" line="821"/>
<source>%1 installed successfully.</source> <source>%1 installed successfully.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="877"/> <location filename="../ui/controllers/installController.cpp" line="855"/>
<source>API config reloaded</source> <source>API config reloaded</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="881"/> <location filename="../ui/controllers/installController.cpp" line="859"/>
<source>Successfully changed the country of connection to %1</source> <source>Successfully changed the country of connection to %1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -2386,97 +2383,107 @@ Already installed containers were found on the server. All installed containers
<translation type="vanished">کنکشن کی ترتیبات یا بیک اپ والی فائل</translation> <translation type="vanished">کنکشن کی ترتیبات یا بیک اپ والی فائل</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
<source>Connection</source> <source>Connection</source>
<translation type="unfinished">کنکشن</translation> <translation type="unfinished">کنکشن</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
<source>Settings</source> <source>Settings</source>
<translation type="unfinished">ترتیبات</translation> <translation type="unfinished">ترتیبات</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
<source>Enable logs</source> <source>Enable logs</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/>
<source>Insert the key, add a configuration file or scan the QR-code</source> <source>Support tag</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="122"/>
<source>Insert key</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
<source>Copied</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="140"/>
<source>Insert the key, add a configuration file or scan the QR-code</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="150"/>
<source>Insert key</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="151"/>
<source>Insert</source> <source>Insert</source>
<translation type="unfinished">داخل کریں</translation> <translation type="unfinished">داخل کریں</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
<source>Continue</source> <source>Continue</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="161"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="189"/>
<source>Other connection options</source> <source>Other connection options</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="172"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="200"/>
<source>VPN by Amnezia</source> <source>VPN by Amnezia</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="173"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="201"/>
<source>Connect to classic paid and free VPN services from Amnezia</source> <source>Connect to classic paid and free VPN services from Amnezia</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="196"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
<source>Self-hosted VPN</source> <source>Self-hosted VPN</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="197"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="225"/>
<source>Configure Amnezia VPN on your own server</source> <source>Configure Amnezia VPN on your own server</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="217"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="245"/>
<source>Restore from backup</source> <source>Restore from backup</source>
<translation type="unfinished">بیک اپ سے بحال کریں</translation> <translation type="unfinished">بیک اپ سے بحال کریں</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="223"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="251"/>
<source>Open backup file</source> <source>Open backup file</source>
<translation type="unfinished">بیک اپ فائل کو کھولیں</translation> <translation type="unfinished">بیک اپ فائل کو کھولیں</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="252"/>
<source>Backup files (*.backup)</source> <source>Backup files (*.backup)</source>
<translation type="unfinished">بیک اپ فائلیں (*.backup)</translation> <translation type="unfinished">بیک اپ فائلیں (*.backup)</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="241"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="269"/>
<source>File with connection settings</source> <source>File with connection settings</source>
<translation>کنکشن کی ترتیبات والی فائل</translation> <translation>کنکشن کی ترتیبات والی فائل</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="249"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="277"/>
<source>Open config file</source> <source>Open config file</source>
<translation>کنفیگ فائل کو کھولیں</translation> <translation>کنفیگ فائل کو کھولیں</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
<source>QR code</source> <source>QR code</source>
<translation>QR کوڈ</translation> <translation>QR کوڈ</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="291"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="319"/>
<source>I have nothing</source> <source>I have nothing</source>
<translation type="unfinished">میرے پاس کچھ نہیں ہے</translation> <translation type="unfinished">میرے پاس کچھ نہیں ہے</translation>
</message> </message>
@ -2861,27 +2868,27 @@ Already installed containers were found on the server. All installed containers
<translation>تلاش</translation> <translation>تلاش</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="817"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="814"/>
<source>Creation date: %1</source> <source>Creation date: %1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="825"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="822"/>
<source>Latest handshake: %1</source> <source>Latest handshake: %1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="833"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="830"/>
<source>Data received: %1</source> <source>Data received: %1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="841"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="838"/>
<source>Data sent: %1</source> <source>Data sent: %1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="849"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
<source>Allowed IPs: %1</source> <source>Allowed IPs: %1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -2890,42 +2897,42 @@ Already installed containers were found on the server. All installed containers
<translation type="vanished">تخلیق کی تاریخ: </translation> <translation type="vanished">تخلیق کی تاریخ: </translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="870"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
<source>Rename</source> <source>Rename</source>
<translation>نام تبدیل</translation> <translation>نام تبدیل</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="916"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
<source>Client name</source> <source>Client name</source>
<translation>کلائنٹ کا نام</translation> <translation>کلائنٹ کا نام</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="929"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
<source>Save</source> <source>Save</source>
<translation>محفوظ</translation> <translation>محفوظ</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="963"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
<source>Revoke</source> <source>Revoke</source>
<translation>واپس لین</translation> <translation>واپس لین</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
<source>Revoke the config for a user - %1?</source> <source>Revoke the config for a user - %1?</source>
<translation>کیا آپ مستعمل کے لئے کنفیگ کو واپس لینا چاہتے ہیں - %1؟</translation> <translation>کیا آپ مستعمل کے لئے کنفیگ کو واپس لینا چاہتے ہیں - %1؟</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="968"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
<source>The user will no longer be able to connect to your server.</source> <source>The user will no longer be able to connect to your server.</source>
<translation>صارف آپ کے سرور سے متصل ہونے کا اختیار نہیں رہے گا.</translation> <translation>صارف آپ کے سرور سے متصل ہونے کا اختیار نہیں رہے گا.</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="969"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
<source>Continue</source> <source>Continue</source>
<translation>جاری رکھیں</translation> <translation>جاری رکھیں</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="970"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
<source>Cancel</source> <source>Cancel</source>
<translation>منسوخ</translation> <translation>منسوخ</translation>
</message> </message>
@ -3043,17 +3050,17 @@ Already installed containers were found on the server. All installed containers
<context> <context>
<name>PageStart</name> <name>PageStart</name>
<message> <message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="198"/> <location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
<source>Logging was disabled after 14 days, log files were deleted</source> <source>Logging was disabled after 14 days, log files were deleted</source>
<translation>لاگنگ کو 14 دنوں کے بعد غیر فعال کر دیا گیا، لاگ فائلوں کو حذف کر دیا گیا</translation> <translation>لاگنگ کو 14 دنوں کے بعد غیر فعال کر دیا گیا، لاگ فائلوں کو حذف کر دیا گیا</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/> <location filename="../ui/qml/Pages2/PageStart.qml" line="206"/>
<source>Settings restored from backup file</source> <source>Settings restored from backup file</source>
<translation type="unfinished">ترتیبات بیک اپ فائل سے بحال کردی گئی ہیں</translation> <translation type="unfinished">ترتیبات بیک اپ فائل سے بحال کردی گئی ہیں</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="208"/> <location filename="../ui/qml/Pages2/PageStart.qml" line="212"/>
<source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source> <source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -3392,22 +3399,22 @@ Already installed containers were found on the server. All installed containers
<translation>سرور سے منسلک ہونے کا ٹائم آؤٹ</translation> <translation>سرور سے منسلک ہونے کا ٹائم آؤٹ</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="55"/> <location filename="../core/errorstrings.cpp" line="56"/>
<source>VPN connection error</source> <source>VPN connection error</source>
<translation>VPN کنکشن کی خرابی</translation> <translation>VPN کنکشن کی خرابی</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="58"/> <location filename="../core/errorstrings.cpp" line="59"/>
<source>Error when retrieving configuration from API</source> <source>Error when retrieving configuration from API</source>
<translation>آپی سے کنفیگریشن بازیافت کرتے وقت خرابی</translation> <translation>آپی سے کنفیگریشن بازیافت کرتے وقت خرابی</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="59"/> <location filename="../core/errorstrings.cpp" line="60"/>
<source>This config has already been added to the application</source> <source>This config has already been added to the application</source>
<translation>یہ تشکیل پہلے ہی ایپلی کیشن میں شامل کی جا چکی ہے</translation> <translation>یہ تشکیل پہلے ہی ایپلی کیشن میں شامل کی جا چکی ہے</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="78"/> <location filename="../core/errorstrings.cpp" line="80"/>
<source>ErrorCode: %1. </source> <source>ErrorCode: %1. </source>
<translation>ایرر کوڈ: %1. </translation> <translation>ایرر کوڈ: %1. </translation>
</message> </message>
@ -3482,57 +3489,67 @@ Already installed containers were found on the server. All installed containers
<translation>ترتیب میں سرور سے منسلک ہونے کے لیے کوئی کنٹینرز اور اسناد نہیں ہیں</translation> <translation>ترتیب میں سرور سے منسلک ہونے کے لیے کوئی کنٹینرز اور اسناد نہیں ہیں</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="60"/> <location filename="../core/errorstrings.cpp" line="53"/>
<source>In the response from the server, an empty config was received</source> <source>Unable to open config file</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="61"/> <location filename="../core/errorstrings.cpp" line="61"/>
<source>SSL error occurred</source> <source>In the response from the server, an empty config was received</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="62"/> <location filename="../core/errorstrings.cpp" line="62"/>
<source>Server response timeout on api request</source> <source>SSL error occurred</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="63"/> <location filename="../core/errorstrings.cpp" line="63"/>
<source>Server response timeout on api request</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="64"/>
<source>Missing AGW public key</source> <source>Missing AGW public key</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="66"/> <location filename="../core/errorstrings.cpp" line="65"/>
<source>Failed to decrypt response payload</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="68"/>
<source>QFile error: The file could not be opened</source> <source>QFile error: The file could not be opened</source>
<translation>QFile کی خرابی: فائل کو نہیں کھولا جا سکا</translation> <translation>QFile کی خرابی: فائل کو نہیں کھولا جا سکا</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="67"/> <location filename="../core/errorstrings.cpp" line="69"/>
<source>QFile error: An error occurred when reading from the file</source> <source>QFile error: An error occurred when reading from the file</source>
<translation>کیو فائل کی خرابی: فائل سے پڑھتے وقت ایک خرابی پیش آگئی</translation> <translation>کیو فائل کی خرابی: فائل سے پڑھتے وقت ایک خرابی پیش آگئی</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="68"/> <location filename="../core/errorstrings.cpp" line="70"/>
<source>QFile error: The file could not be accessed</source> <source>QFile error: The file could not be accessed</source>
<translation>QFile کی خرابی: فائل تک رسائی نہیں ہو سکی</translation> <translation>QFile کی خرابی: فائل تک رسائی نہیں ہو سکی</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="69"/> <location filename="../core/errorstrings.cpp" line="71"/>
<source>QFile error: An unspecified error occurred</source> <source>QFile error: An unspecified error occurred</source>
<translation>کیو فائل میں خرابی: ایک غیر متعینہ خرابی پیش آگئی</translation> <translation>کیو فائل میں خرابی: ایک غیر متعینہ خرابی پیش آگئی</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="70"/> <location filename="../core/errorstrings.cpp" line="72"/>
<source>QFile error: A fatal error occurred</source> <source>QFile error: A fatal error occurred</source>
<translation>کیو فائل میں خرابی: ایک مہلک خرابی پیش آگئی</translation> <translation>کیو فائل میں خرابی: ایک مہلک خرابی پیش آگئی</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="71"/> <location filename="../core/errorstrings.cpp" line="73"/>
<source>QFile error: The operation was aborted</source> <source>QFile error: The operation was aborted</source>
<translation>کیو فائل کی خرابی: آپریشن روک دیا گیا تھا</translation> <translation>کیو فائل کی خرابی: آپریشن روک دیا گیا تھا</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="75"/> <location filename="../core/errorstrings.cpp" line="77"/>
<source>Internal error</source> <source>Internal error</source>
<translation>داخلی خامی</translation> <translation>داخلی خامی</translation>
</message> </message>
@ -4073,7 +4090,7 @@ While it offers a blend of security, stability, and speed, it&apos;s essential t
<context> <context>
<name>VpnConnection</name> <name>VpnConnection</name>
<message> <message>
<location filename="../vpnconnection.cpp" line="408"/> <location filename="../vpnconnection.cpp" line="409"/>
<source>Mbps</source> <source>Mbps</source>
<translation>ایم بی پی ایس</translation> <translation>ایم بی پی ایس</translation>
</message> </message>

View file

@ -89,60 +89,60 @@
<name>ConnectionController</name> <name>ConnectionController</name>
<message> <message>
<location filename="../ui/controllers/connectionController.h" line="80"/> <location filename="../ui/controllers/connectionController.h" line="80"/>
<location filename="../ui/controllers/connectionController.cpp" line="100"/> <location filename="../ui/controllers/connectionController.cpp" line="103"/>
<location filename="../ui/controllers/connectionController.cpp" line="115"/> <location filename="../ui/controllers/connectionController.cpp" line="118"/>
<location filename="../ui/controllers/connectionController.cpp" line="121"/> <location filename="../ui/controllers/connectionController.cpp" line="124"/>
<source>Connect</source> <source>Connect</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="214"/> <location filename="../ui/controllers/connectionController.cpp" line="217"/>
<source>VPN Protocols is not installed. <source>VPN Protocols is not installed.
Please install VPN container at first</source> Please install VPN container at first</source>
<translation>VPN协议</translation> <translation>VPN协议</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="81"/> <location filename="../ui/controllers/connectionController.cpp" line="84"/>
<source>Connecting...</source> <source>Connecting...</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="86"/> <location filename="../ui/controllers/connectionController.cpp" line="89"/>
<source>Connected</source> <source>Connected</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="95"/> <location filename="../ui/controllers/connectionController.cpp" line="98"/>
<source>Reconnecting...</source> <source>Reconnecting...</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="105"/> <location filename="../ui/controllers/connectionController.cpp" line="108"/>
<source>Disconnecting...</source> <source>Disconnecting...</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="110"/> <location filename="../ui/controllers/connectionController.cpp" line="113"/>
<source>Preparing...</source> <source>Preparing...</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="132"/> <location filename="../ui/controllers/connectionController.cpp" line="135"/>
<source>Settings updated successfully, reconnnection...</source> <source>Settings updated successfully, reconnnection...</source>
<translation>, ...</translation> <translation>, ...</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="135"/> <location filename="../ui/controllers/connectionController.cpp" line="138"/>
<source>Settings updated successfully</source> <source>Settings updated successfully</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="209"/> <location filename="../ui/controllers/connectionController.cpp" line="212"/>
<source>The selected protocol is not supported on the current platform</source> <source>The selected protocol is not supported on the current platform</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/connectionController.cpp" line="233"/> <location filename="../ui/controllers/connectionController.cpp" line="236"/>
<source>unable to create configuration</source> <source>unable to create configuration</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -257,23 +257,12 @@ Can&apos;t be disabled for current server</source>
<context> <context>
<name>ImportController</name> <name>ImportController</name>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="87"/> <location filename="../ui/controllers/importController.cpp" line="623"/>
<source>Unable to open file</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/controllers/importController.cpp" line="191"/>
<location filename="../ui/controllers/importController.cpp" line="196"/>
<source>Invalid configuration file</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/controllers/importController.cpp" line="622"/>
<source>Scanned %1 of %2.</source> <source>Scanned %1 of %2.</source>
<translation> %1 of %2.</translation> <translation> %1 of %2.</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/importController.cpp" line="657"/> <location filename="../ui/controllers/importController.cpp" line="658"/>
<source>In the imported configuration, potentially dangerous lines were found:</source> <source>In the imported configuration, potentially dangerous lines were found:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -289,75 +278,75 @@ Can&apos;t be disabled for current server</source>
<translation type="obsolete"> </translation> <translation type="obsolete"> </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="181"/> <location filename="../ui/controllers/installController.cpp" line="157"/>
<source>%1 installed successfully. </source> <source>%1 installed successfully. </source>
<translation>%1 </translation> <translation>%1 </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="183"/> <location filename="../ui/controllers/installController.cpp" line="159"/>
<source>%1 is already installed on the server. </source> <source>%1 is already installed on the server. </source>
<translation> %1</translation> <translation> %1</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="203"/> <location filename="../ui/controllers/installController.cpp" line="179"/>
<source> <source>
Added containers that were already installed on the server</source> Added containers that were already installed on the server</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="283"/> <location filename="../ui/controllers/installController.cpp" line="259"/>
<source> <source>
Already installed containers were found on the server. All installed containers have been added to the application</source> Already installed containers were found on the server. All installed containers have been added to the application</source>
<translation> <translation>
</translation> </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="541"/> <location filename="../ui/controllers/installController.cpp" line="517"/>
<source>Settings updated successfully</source> <source>Settings updated successfully</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="558"/> <location filename="../ui/controllers/installController.cpp" line="534"/>
<source>Server &apos;%1&apos; was rebooted</source> <source>Server &apos;%1&apos; was rebooted</source>
<translation> &apos;%1&apos; </translation> <translation> &apos;%1&apos; </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="570"/> <location filename="../ui/controllers/installController.cpp" line="546"/>
<source>Server &apos;%1&apos; was removed</source> <source>Server &apos;%1&apos; was removed</source>
<translation> &apos;%1&apos;</translation> <translation> &apos;%1&apos;</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="581"/> <location filename="../ui/controllers/installController.cpp" line="557"/>
<source>All containers from server &apos;%1&apos; have been removed</source> <source>All containers from server &apos;%1&apos; have been removed</source>
<translation> &apos;%1&apos; </translation> <translation> &apos;%1&apos; </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="599"/> <location filename="../ui/controllers/installController.cpp" line="575"/>
<source>%1 has been removed from the server &apos;%2&apos;</source> <source>%1 has been removed from the server &apos;%2&apos;</source>
<translation>%1 &apos;%2&apos; </translation> <translation>%1 &apos;%2&apos; </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="608"/> <location filename="../ui/controllers/installController.cpp" line="584"/>
<source>Api config removed</source> <source>Api config removed</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="630"/> <location filename="../ui/controllers/installController.cpp" line="606"/>
<source>%1 cached profile cleared</source> <source>%1 cached profile cleared</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="845"/> <location filename="../ui/controllers/installController.cpp" line="821"/>
<source>%1 installed successfully.</source> <source>%1 installed successfully.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="877"/> <location filename="../ui/controllers/installController.cpp" line="855"/>
<source>API config reloaded</source> <source>API config reloaded</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="881"/> <location filename="../ui/controllers/installController.cpp" line="859"/>
<source>Successfully changed the country of connection to %1</source> <source>Successfully changed the country of connection to %1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -378,12 +367,12 @@ Already installed containers were found on the server. All installed containers
<translation type="obsolete"> </translation> <translation type="obsolete"> </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="769"/> <location filename="../ui/controllers/installController.cpp" line="745"/>
<source>Please login as the user</source> <source>Please login as the user</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="797"/> <location filename="../ui/controllers/installController.cpp" line="773"/>
<source>Server added successfully</source> <source>Server added successfully</source>
<translation></translation> <translation></translation>
</message> </message>
@ -2549,97 +2538,107 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<translation type="vanished"></translation> <translation type="vanished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
<source>Connection</source> <source>Connection</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
<source>Settings</source> <source>Settings</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
<source>Enable logs</source> <source>Enable logs</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/>
<source>Insert the key, add a configuration file or scan the QR-code</source> <source>Support tag</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="122"/>
<source>Insert key</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
<source>Copied</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="140"/>
<source>Insert the key, add a configuration file or scan the QR-code</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="150"/>
<source>Insert key</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="151"/>
<source>Insert</source> <source>Insert</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
<source>Continue</source> <source>Continue</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="161"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="189"/>
<source>Other connection options</source> <source>Other connection options</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="172"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="200"/>
<source>VPN by Amnezia</source> <source>VPN by Amnezia</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="173"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="201"/>
<source>Connect to classic paid and free VPN services from Amnezia</source> <source>Connect to classic paid and free VPN services from Amnezia</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="196"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
<source>Self-hosted VPN</source> <source>Self-hosted VPN</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="197"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="225"/>
<source>Configure Amnezia VPN on your own server</source> <source>Configure Amnezia VPN on your own server</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="217"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="245"/>
<source>Restore from backup</source> <source>Restore from backup</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="223"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="251"/>
<source>Open backup file</source> <source>Open backup file</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="252"/>
<source>Backup files (*.backup)</source> <source>Backup files (*.backup)</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="241"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="269"/>
<source>File with connection settings</source> <source>File with connection settings</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="249"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="277"/>
<source>Open config file</source> <source>Open config file</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
<source>QR code</source> <source>QR code</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="291"/> <location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="319"/>
<source>I have nothing</source> <source>I have nothing</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -3067,27 +3066,27 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="817"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="814"/>
<source>Creation date: %1</source> <source>Creation date: %1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="825"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="822"/>
<source>Latest handshake: %1</source> <source>Latest handshake: %1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="833"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="830"/>
<source>Data received: %1</source> <source>Data received: %1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="841"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="838"/>
<source>Data sent: %1</source> <source>Data sent: %1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="849"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
<source>Allowed IPs: %1</source> <source>Allowed IPs: %1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -3096,42 +3095,42 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation type="vanished">: </translation> <translation type="vanished">: </translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="870"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
<source>Rename</source> <source>Rename</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="916"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
<source>Client name</source> <source>Client name</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="929"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
<source>Save</source> <source>Save</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="963"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
<source>Revoke</source> <source>Revoke</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
<source>Revoke the config for a user - %1?</source> <source>Revoke the config for a user - %1?</source>
<translation>- %1?</translation> <translation>- %1?</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="968"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
<source>The user will no longer be able to connect to your server.</source> <source>The user will no longer be able to connect to your server.</source>
<translation>.</translation> <translation>.</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="969"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
<source>Continue</source> <source>Continue</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="970"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
<source>Cancel</source> <source>Cancel</source>
<translation></translation> <translation></translation>
</message> </message>
@ -3288,17 +3287,17 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<context> <context>
<name>PageStart</name> <name>PageStart</name>
<message> <message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="198"/> <location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
<source>Logging was disabled after 14 days, log files were deleted</source> <source>Logging was disabled after 14 days, log files were deleted</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/> <location filename="../ui/qml/Pages2/PageStart.qml" line="206"/>
<source>Settings restored from backup file</source> <source>Settings restored from backup file</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="208"/> <location filename="../ui/qml/Pages2/PageStart.qml" line="212"/>
<source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source> <source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -3651,6 +3650,11 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<source>SCP error: Generic failure</source> <source>SCP error: Generic failure</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<location filename="../core/errorstrings.cpp" line="53"/>
<source>Unable to open config file</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>Sftp error: End-of-file encountered</source> <source>Sftp error: End-of-file encountered</source>
<translation type="vanished">Sftp错误: End-of-file encountered</translation> <translation type="vanished">Sftp错误: End-of-file encountered</translation>
@ -3704,72 +3708,77 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation type="vanished">Sftp 错误: 远程驱动器中没有媒介</translation> <translation type="vanished">Sftp 错误: 远程驱动器中没有媒介</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="55"/> <location filename="../core/errorstrings.cpp" line="56"/>
<source>VPN connection error</source> <source>VPN connection error</source>
<translation>VPN </translation> <translation>VPN </translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="58"/> <location filename="../core/errorstrings.cpp" line="59"/>
<source>Error when retrieving configuration from API</source> <source>Error when retrieving configuration from API</source>
<translation> API </translation> <translation> API </translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="59"/> <location filename="../core/errorstrings.cpp" line="60"/>
<source>This config has already been added to the application</source> <source>This config has already been added to the application</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="60"/> <location filename="../core/errorstrings.cpp" line="61"/>
<source>In the response from the server, an empty config was received</source> <source>In the response from the server, an empty config was received</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="61"/> <location filename="../core/errorstrings.cpp" line="62"/>
<source>SSL error occurred</source> <source>SSL error occurred</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="62"/> <location filename="../core/errorstrings.cpp" line="63"/>
<source>Server response timeout on api request</source> <source>Server response timeout on api request</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="63"/> <location filename="../core/errorstrings.cpp" line="64"/>
<source>Missing AGW public key</source> <source>Missing AGW public key</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="66"/> <location filename="../core/errorstrings.cpp" line="65"/>
<source>QFile error: The file could not be opened</source> <source>Failed to decrypt response payload</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="67"/>
<source>QFile error: An error occurred when reading from the file</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="68"/> <location filename="../core/errorstrings.cpp" line="68"/>
<source>QFile error: The file could not be accessed</source> <source>QFile error: The file could not be opened</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="69"/> <location filename="../core/errorstrings.cpp" line="69"/>
<source>QFile error: An unspecified error occurred</source> <source>QFile error: An error occurred when reading from the file</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="70"/> <location filename="../core/errorstrings.cpp" line="70"/>
<source>QFile error: A fatal error occurred</source> <source>QFile error: The file could not be accessed</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="71"/> <location filename="../core/errorstrings.cpp" line="71"/>
<source>QFile error: An unspecified error occurred</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="72"/>
<source>QFile error: A fatal error occurred</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="73"/>
<source>QFile error: The operation was aborted</source> <source>QFile error: The operation was aborted</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="78"/> <location filename="../core/errorstrings.cpp" line="80"/>
<source>ErrorCode: %1. </source> <source>ErrorCode: %1. </source>
<translation>: %1. </translation> <translation>: %1. </translation>
</message> </message>
@ -3837,7 +3846,7 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation type="vanished"></translation> <translation type="vanished"></translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="75"/> <location filename="../core/errorstrings.cpp" line="77"/>
<source>Internal error</source> <source>Internal error</source>
<translation></translation> <translation></translation>
</message> </message>
@ -4517,7 +4526,7 @@ While it offers a blend of security, stability, and speed, it&apos;s essential t
<context> <context>
<name>VpnConnection</name> <name>VpnConnection</name>
<message> <message>
<location filename="../vpnconnection.cpp" line="408"/> <location filename="../vpnconnection.cpp" line="409"/>
<source>Mbps</source> <source>Mbps</source>
<translation></translation> <translation></translation>
</message> </message>

View file

@ -34,13 +34,13 @@ ConnectionController::ConnectionController(const QSharedPointer<ServersModel> &s
void ConnectionController::openConnection() void ConnectionController::openConnection()
{ {
// #if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) #if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
// if (!Utils::processIsRunning(Utils::executable(SERVICE_NAME, false), true)) if (!Utils::processIsRunning(Utils::executable(SERVICE_NAME, false), true))
// { {
// emit connectionErrorOccurred(ErrorCode::AmneziaServiceNotRunning); emit connectionErrorOccurred(ErrorCode::AmneziaServiceNotRunning);
// return; return;
// } }
// #endif #endif
int serverIndex = m_serversModel->getDefaultServerIndex(); int serverIndex = m_serversModel->getDefaultServerIndex();
QJsonObject serverConfig = m_serversModel->getServerConfig(serverIndex); QJsonObject serverConfig = m_serversModel->getServerConfig(serverIndex);
@ -51,6 +51,9 @@ void ConnectionController::openConnection()
if (configVersion == ApiConfigSources::Telegram if (configVersion == ApiConfigSources::Telegram
&& !m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) { && !m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
emit updateApiConfigFromTelegram(); emit updateApiConfigFromTelegram();
} else if (configVersion == ApiConfigSources::AmneziaGateway
&& !m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
emit updateApiConfigFromGateway();
} else if (configVersion && m_serversModel->isApiKeyExpired(serverIndex)) { } else if (configVersion && m_serversModel->isApiKeyExpired(serverIndex)) {
qDebug() << "attempt to update api config by end_date event"; qDebug() << "attempt to update api config by end_date event";
if (configVersion == ApiConfigSources::Telegram) { if (configVersion == ApiConfigSources::Telegram) {

View file

@ -39,11 +39,12 @@ namespace
const QString amneziaConfigPatternUserName = "userName"; const QString amneziaConfigPatternUserName = "userName";
const QString amneziaConfigPatternPassword = "password"; const QString amneziaConfigPatternPassword = "password";
const QString amneziaFreeConfigPattern = "api_key"; const QString amneziaFreeConfigPattern = "api_key";
const QString amneziaPremiumConfigPattern = "auth_data";
const QString backupPattern = "Servers/serversList"; const QString backupPattern = "Servers/serversList";
if (config.contains(backupPattern)) { if (config.contains(backupPattern)) {
return ConfigTypes::Backup; return ConfigTypes::Backup;
} else if (config.contains(amneziaConfigPattern) || config.contains(amneziaFreeConfigPattern) } else if (config.contains(amneziaConfigPattern) || config.contains(amneziaFreeConfigPattern) || config.contains(amneziaPremiumConfigPattern)
|| (config.contains(amneziaConfigPatternHostName) && config.contains(amneziaConfigPatternUserName) || (config.contains(amneziaConfigPatternHostName) && config.contains(amneziaConfigPatternUserName)
&& config.contains(amneziaConfigPatternPassword))) { && config.contains(amneziaConfigPatternPassword))) {
return ConfigTypes::Amnezia; return ConfigTypes::Amnezia;
@ -84,7 +85,7 @@ bool ImportController::extractConfigFromFile(const QString &fileName)
return extractConfigFromData(data); return extractConfigFromData(data);
} }
emit importErrorOccurred(tr("Unable to open file"), false); emit importErrorOccurred(ErrorCode::ImportOpenConfigError, false);
return false; return false;
} }
@ -188,12 +189,12 @@ bool ImportController::extractConfigFromData(QString data)
if (!m_serversModel->getServersCount()) { if (!m_serversModel->getServersCount()) {
emit restoreAppConfig(config.toUtf8()); emit restoreAppConfig(config.toUtf8());
} else { } else {
emit importErrorOccurred(tr("Invalid configuration file"), false); emit importErrorOccurred(ErrorCode::ImportInvalidConfigError, false);
} }
break; break;
} }
case ConfigTypes::Invalid: { case ConfigTypes::Invalid: {
emit importErrorOccurred(tr("Invalid configuration file"), false); emit importErrorOccurred(ErrorCode::ImportInvalidConfigError, false);
break; break;
} }
} }

View file

@ -54,7 +54,6 @@ public slots:
signals: signals:
void importFinished(); void importFinished();
void importErrorOccurred(const QString &errorMessage, bool goToPageHome);
void importErrorOccurred(ErrorCode errorCode, bool goToPageHome); void importErrorOccurred(ErrorCode errorCode, bool goToPageHome);
void qrDecodingFinished(); void qrDecodingFinished();

48
client/ui/controllers/installController.cpp Normal file → Executable file
View file

@ -32,32 +32,8 @@ namespace
constexpr char availableCountries[] = "available_countries"; constexpr char availableCountries[] = "available_countries";
constexpr char apiConfig[] = "api_config"; constexpr char apiConfig[] = "api_config";
constexpr char authData[] = "auth_data";
} }
#ifdef Q_OS_WINDOWS
QString getNextDriverLetter()
{
QProcess drivesProc;
drivesProc.start("wmic logicaldisk get caption");
drivesProc.waitForFinished();
QString drives = drivesProc.readAll();
qDebug() << drives;
QString letters = "CFGHIJKLMNOPQRSTUVWXYZ";
QString letter;
for (int i = letters.size() - 1; i > 0; i--) {
letter = letters.at(i);
if (!drives.contains(letter + ":"))
break;
}
if (letter == "C:") {
// set err info
qDebug() << "Can't find free drive letter";
return "";
}
return letter;
}
#endif
} }
InstallController::InstallController(const QSharedPointer<ServersModel> &serversModel, const QSharedPointer<ContainersModel> &containersModel, InstallController::InstallController(const QSharedPointer<ServersModel> &serversModel, const QSharedPointer<ContainersModel> &containersModel,
@ -135,10 +111,10 @@ void InstallController::install(DockerContainer container, int port, TransportPr
containerConfig[config_key::transportPacketMagicHeader] = transportPacketMagicHeader; containerConfig[config_key::transportPacketMagicHeader] = transportPacketMagicHeader;
} else if (container == DockerContainer::Sftp) { } else if (container == DockerContainer::Sftp) {
containerConfig.insert(config_key::userName, protocols::sftp::defaultUserName); containerConfig.insert(config_key::userName, protocols::sftp::defaultUserName);
containerConfig.insert(config_key::password, Utils::getRandomString(10)); containerConfig.insert(config_key::password, Utils::getRandomString(16));
} else if (container == DockerContainer::Socks5Proxy) { } else if (container == DockerContainer::Socks5Proxy) {
containerConfig.insert(config_key::userName, protocols::socks5Proxy::defaultUserName); containerConfig.insert(config_key::userName, protocols::socks5Proxy::defaultUserName);
containerConfig.insert(config_key::password, Utils::getRandomString(10)); containerConfig.insert(config_key::password, Utils::getRandomString(16));
} }
config.insert(config_key::container, ContainerProps::containerToString(container)); config.insert(config_key::container, ContainerProps::containerToString(container));
@ -667,7 +643,7 @@ void InstallController::mountSftpDrive(const QString &port, const QString &passw
QString hostname = serverCredentials.hostName; QString hostname = serverCredentials.hostName;
#ifdef Q_OS_WINDOWS #ifdef Q_OS_WINDOWS
mountPath = getNextDriverLetter() + ":"; mountPath = Utils::getNextDriverLetter() + ":";
// QString cmd = QString("net use \\\\sshfs\\%1@x.x.x.x!%2 /USER:%1 %3") // QString cmd = QString("net use \\\\sshfs\\%1@x.x.x.x!%2 /USER:%1 %3")
// .arg(labelTftpUserNameText()) // .arg(labelTftpUserNameText())
// .arg(labelTftpPortText()) // .arg(labelTftpPortText())
@ -768,7 +744,7 @@ bool InstallController::checkSshConnection(QSharedPointer<ServerController> serv
} else { } else {
if (output.contains(tr("Please login as the user"))) { if (output.contains(tr("Please login as the user"))) {
output.replace("\n", ""); output.replace("\n", "");
emit installationErrorOccurred(output); emit wrongInstallationUser(output);
return false; return false;
} }
} }
@ -826,7 +802,7 @@ bool InstallController::installServiceFromApi()
ErrorCode errorCode = apiController.getConfigForService(m_settings->getInstallationUuid(true), m_apiServicesModel->getCountryCode(), ErrorCode errorCode = apiController.getConfigForService(m_settings->getInstallationUuid(true), m_apiServicesModel->getCountryCode(),
m_apiServicesModel->getSelectedServiceType(), m_apiServicesModel->getSelectedServiceType(),
m_apiServicesModel->getSelectedServiceProtocol(), "", serverConfig); m_apiServicesModel->getSelectedServiceProtocol(), "", QJsonObject(), serverConfig);
if (errorCode != ErrorCode::NoError) { if (errorCode != ErrorCode::NoError) {
emit installationErrorOccurred(errorCode); emit installationErrorOccurred(errorCode);
return false; return false;
@ -853,24 +829,26 @@ bool InstallController::updateServiceFromApi(const int serverIndex, const QStrin
auto serverConfig = m_serversModel->getServerConfig(serverIndex); auto serverConfig = m_serversModel->getServerConfig(serverIndex);
auto apiConfig = serverConfig.value(configKey::apiConfig).toObject(); auto apiConfig = serverConfig.value(configKey::apiConfig).toObject();
auto authData = serverConfig.value(configKey::authData).toObject();
QJsonObject newServerConfig; QJsonObject newServerConfig;
ErrorCode errorCode = ErrorCode errorCode = apiController.getConfigForService(
apiController.getConfigForService(m_settings->getInstallationUuid(true), apiConfig.value(configKey::userCountryCode).toString(), m_settings->getInstallationUuid(true), apiConfig.value(configKey::userCountryCode).toString(),
apiConfig.value(configKey::serviceType).toString(), apiConfig.value(configKey::serviceType).toString(), apiConfig.value(configKey::serviceProtocol).toString(), newCountryCode,
apiConfig.value(configKey::serviceProtocol).toString(), newCountryCode, newServerConfig); authData, newServerConfig);
if (errorCode != ErrorCode::NoError) { if (errorCode != ErrorCode::NoError) {
emit installationErrorOccurred(errorCode); emit installationErrorOccurred(errorCode);
return false; return false;
} }
QJsonObject newApiConfig = newServerConfig.value(configKey::apiConfig).toObject(); QJsonObject newApiConfig = newServerConfig.value(configKey::apiConfig).toObject();
newApiConfig.insert(configKey::serviceInfo, apiConfig.value(configKey::serviceInfo));
newApiConfig.insert(configKey::userCountryCode, apiConfig.value(configKey::userCountryCode)); newApiConfig.insert(configKey::userCountryCode, apiConfig.value(configKey::userCountryCode));
newApiConfig.insert(configKey::serviceType, apiConfig.value(configKey::serviceType)); newApiConfig.insert(configKey::serviceType, apiConfig.value(configKey::serviceType));
newApiConfig.insert(configKey::serviceProtocol, apiConfig.value(configKey::serviceProtocol)); newApiConfig.insert(configKey::serviceProtocol, apiConfig.value(configKey::serviceProtocol));
newServerConfig.insert(configKey::apiConfig, newApiConfig); newServerConfig.insert(configKey::apiConfig, newApiConfig);
newServerConfig.insert(configKey::authData, authData);
newServerConfig.insert(config_key::crc, serverConfig.value(config_key::crc));
m_serversModel->editServer(newServerConfig, serverIndex); m_serversModel->editServer(newServerConfig, serverIndex);
if (reloadServiceConfig) { if (reloadServiceConfig) {

View file

@ -75,8 +75,8 @@ signals:
void removeAllContainersFinished(const QString &finishedMessage); void removeAllContainersFinished(const QString &finishedMessage);
void removeProcessedContainerFinished(const QString &finishedMessage); void removeProcessedContainerFinished(const QString &finishedMessage);
void installationErrorOccurred(const QString &errorMessage);
void installationErrorOccurred(ErrorCode errorCode); void installationErrorOccurred(ErrorCode errorCode);
void wrongInstallationUser(const QString &message);
void serverAlreadyExists(int serverIndex); void serverAlreadyExists(int serverIndex);

View file

@ -39,6 +39,9 @@ QVariant ApiCountryModel::data(const QModelIndex &index, int role) const
case CountryNameRole: { case CountryNameRole: {
return countryInfo.value(configKey::serverCountryName).toString(); return countryInfo.value(configKey::serverCountryName).toString();
} }
case CountryImageCodeRole: {
return countryInfo.value(configKey::serverCountryCode).toString().toUpper();
}
} }
return QVariant(); return QVariant();
@ -76,5 +79,6 @@ QHash<int, QByteArray> ApiCountryModel::roleNames() const
QHash<int, QByteArray> roles; QHash<int, QByteArray> roles;
roles[CountryNameRole] = "countryName"; roles[CountryNameRole] = "countryName";
roles[CountryCodeRole] = "countryCode"; roles[CountryCodeRole] = "countryCode";
roles[CountryImageCodeRole] = "countryImageCode";
return roles; return roles;
} }

View file

@ -11,7 +11,8 @@ class ApiCountryModel : public QAbstractListModel
public: public:
enum Roles { enum Roles {
CountryNameRole = Qt::UserRole + 1, CountryNameRole = Qt::UserRole + 1,
CountryCodeRole CountryCodeRole,
CountryImageCodeRole
}; };
explicit ApiCountryModel(QObject *parent = nullptr); explicit ApiCountryModel(QObject *parent = nullptr);

View file

@ -77,6 +77,7 @@ ErrorCode ClientManagementModel::updateModel(const DockerContainer container, co
{ {
beginResetModel(); beginResetModel();
m_clientsTable = QJsonArray(); m_clientsTable = QJsonArray();
endResetModel();
ErrorCode error = ErrorCode::NoError; ErrorCode error = ErrorCode::NoError;
@ -90,10 +91,10 @@ ErrorCode ClientManagementModel::updateModel(const DockerContainer container, co
const QByteArray clientsTableString = serverController->getTextFileFromContainer(container, credentials, clientsTableFile, error); const QByteArray clientsTableString = serverController->getTextFileFromContainer(container, credentials, clientsTableFile, error);
if (error != ErrorCode::NoError) { if (error != ErrorCode::NoError) {
logger.error() << "Failed to get the clientsTable file from the server"; logger.error() << "Failed to get the clientsTable file from the server";
endResetModel();
return error; return error;
} }
beginResetModel();
m_clientsTable = QJsonDocument::fromJson(clientsTableString).array(); m_clientsTable = QJsonDocument::fromJson(clientsTableString).array();
if (m_clientsTable.isEmpty()) { if (m_clientsTable.isEmpty()) {
@ -601,5 +602,6 @@ QHash<int, QByteArray> ClientManagementModel::roleNames() const
roles[LatestHandshakeRole] = "latestHandshake"; roles[LatestHandshakeRole] = "latestHandshake";
roles[DataReceivedRole] = "dataReceived"; roles[DataReceivedRole] = "dataReceived";
roles[DataSentRole] = "dataSent"; roles[DataSentRole] = "dataSent";
roles[AllowedIpsRole] = "allowedIps";
return roles; return roles;
} }

View file

@ -771,5 +771,5 @@ const QString ServersModel::getDefaultServerImagePathCollapsed()
if (countryCode.isEmpty()) { if (countryCode.isEmpty()) {
return ""; return "";
} }
return QString("qrc:/countriesFlags/images/flagKit/%1.svg").arg(countryCode); return QString("qrc:/countriesFlags/images/flagKit/%1.svg").arg(countryCode.toUpper());
} }

View file

@ -90,7 +90,7 @@ PageType {
Layout.rightMargin: 32 Layout.rightMargin: 32
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
source: "qrc:/countriesFlags/images/flagKit/" + countryCode + ".svg" source: "qrc:/countriesFlags/images/flagKit/" + countryImageCode + ".svg"
} }
} }

View file

@ -49,6 +49,8 @@ PageType {
HeaderType { HeaderType {
property bool isVisible: SettingsController.getInstallationUuid() !== "" || PageController.isStartPageVisible()
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 24 Layout.topMargin: 24
Layout.rightMargin: 16 Layout.rightMargin: 16
@ -56,7 +58,7 @@ PageType {
headerText: qsTr("Connection") headerText: qsTr("Connection")
actionButtonImage: PageController.isStartPageVisible() ? "qrc:/images/controls/more-vertical.svg" : "" actionButtonImage: isVisible ? "qrc:/images/controls/more-vertical.svg" : ""
actionButtonFunction: function() { actionButtonFunction: function() {
moreActionsDrawer.open() moreActionsDrawer.open()
} }
@ -67,18 +69,19 @@ PageType {
parent: root parent: root
anchors.fill: parent anchors.fill: parent
expandedHeight: root.height * 0.35 expandedHeight: root.height * 0.5
expandedContent: ColumnLayout { expandedContent: ColumnLayout {
anchors.top: parent.top anchors.top: parent.top
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.leftMargin: 16 spacing: 0
anchors.rightMargin: 16
HeaderType { HeaderType {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 32 Layout.topMargin: 32
Layout.leftMargin: 16
Layout.rightMargin: 16
headerText: qsTr("Settings") headerText: qsTr("Settings")
} }
@ -87,9 +90,12 @@ PageType {
id: switcher id: switcher
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 16 Layout.topMargin: 16
Layout.leftMargin: 16
Layout.rightMargin: 16
text: qsTr("Enable logs") text: qsTr("Enable logs")
visible: PageController.isStartPageVisible()
checked: SettingsController.isLoggingEnabled checked: SettingsController.isLoggingEnabled
onCheckedChanged: { onCheckedChanged: {
if (checked !== SettingsController.isLoggingEnabled) { if (checked !== SettingsController.isLoggingEnabled) {
@ -98,6 +104,28 @@ PageType {
} }
} }
LabelWithButtonType {
id: supportUuid
Layout.fillWidth: true
Layout.topMargin: 16
text: qsTr("Support tag")
descriptionText: SettingsController.getInstallationUuid()
descriptionOnTop: true
rightImageSource: "qrc:/images/controls/copy.svg"
rightImageColor: AmneziaStyle.color.paleGray
visible: SettingsController.getInstallationUuid() !== ""
clickedFunction: function() {
GC.copyToClipBoard(descriptionText)
PageController.showNotificationMessage(qsTr("Copied"))
if (!GC.isMobile()) {
this.rightButton.forceActiveFocus()
}
}
}
} }
} }
} }

View file

@ -37,7 +37,7 @@ PageType {
Connections { Connections {
target: ImportController target: ImportController
function onImportErrorOccurred(errorMessage, goToPageHome) { function onImportErrorOccurred(error, goToPageHome) {
if (goToPageHome) { if (goToPageHome) {
PageController.goToStartPage() PageController.goToStartPage()
} else { } else {

View file

@ -772,7 +772,8 @@ PageType {
} }
} }
anchors.fill: parent width: root.width
height: root.height
expandedContent: ColumnLayout { expandedContent: ColumnLayout {
id: expandedContent id: expandedContent
@ -783,8 +784,6 @@ PageType {
anchors.leftMargin: 16 anchors.leftMargin: 16
anchors.rightMargin: 16 anchors.rightMargin: 16
spacing: 8
onImplicitHeightChanged: { onImplicitHeightChanged: {
clientInfoDrawer.expandedHeight = expandedContent.implicitHeight + 32 clientInfoDrawer.expandedHeight = expandedContent.implicitHeight + 32
} }
@ -797,57 +796,54 @@ PageType {
} }
} }
Header2Type { Header2TextType {
Layout.fillWidth: true Layout.maximumWidth: parent.width
headerText: clientName
}
ColumnLayout
{
id: textColumn
property string textColor: AmneziaStyle.color.mutedGray
Layout.bottomMargin: 24 Layout.bottomMargin: 24
ParagraphTextType { text: clientName
color: textColumn.textColor maximumLineCount: 2
visible: creationDate wrapMode: Text.Wrap
Layout.fillWidth: true elide: Qt.ElideRight
}
text: qsTr("Creation date: %1").arg(creationDate) ParagraphTextType {
} color: AmneziaStyle.color.mutedGray
visible: creationDate
Layout.fillWidth: true
ParagraphTextType { text: qsTr("Creation date: %1").arg(creationDate)
color: textColumn.textColor }
visible: latestHandshake
Layout.fillWidth: true
text: qsTr("Latest handshake: %1").arg(latestHandshake) ParagraphTextType {
} color: AmneziaStyle.color.mutedGray
visible: latestHandshake
Layout.fillWidth: true
ParagraphTextType { text: qsTr("Latest handshake: %1").arg(latestHandshake)
color: textColumn.textColor }
visible: dataReceived
Layout.fillWidth: true
text: qsTr("Data received: %1").arg(dataReceived) ParagraphTextType {
} color: AmneziaStyle.color.mutedGray
visible: dataReceived
Layout.fillWidth: true
ParagraphTextType { text: qsTr("Data received: %1").arg(dataReceived)
color: textColumn.textColor }
visible: dataSent
Layout.fillWidth: true
text: qsTr("Data sent: %1").arg(dataSent) ParagraphTextType {
} color: AmneziaStyle.color.mutedGray
visible: dataSent
Layout.fillWidth: true
ParagraphTextType { text: qsTr("Data sent: %1").arg(dataSent)
color: textColumn.textColor }
visible: allowedIps
Layout.fillWidth: true
text: qsTr("Allowed IPs: %1").arg(allowedIps) ParagraphTextType {
} color: AmneziaStyle.color.mutedGray
visible: allowedIps
Layout.fillWidth: true
text: qsTr("Allowed IPs: %1").arg(allowedIps)
} }
Item { Item {
@ -952,6 +948,7 @@ PageType {
BasicButtonType { BasicButtonType {
id: revokeButton id: revokeButton
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 8
defaultColor: AmneziaStyle.color.transparent defaultColor: AmneziaStyle.color.transparent
hoveredColor: AmneziaStyle.color.translucentWhite hoveredColor: AmneziaStyle.color.translucentWhite

View file

@ -123,6 +123,10 @@ PageType {
} }
} }
function onWrongInstallationUser(message) {
onInstallationErrorOccurred(message)
}
function onUpdateContainerFinished(message) { function onUpdateContainerFinished(message) {
PageController.showNotificationMessage(message) PageController.showNotificationMessage(message)
PageController.closePage() PageController.closePage()

169
client/utilities.cpp Normal file → Executable file
View file

@ -10,18 +10,72 @@
#include <QJsonObject> #include <QJsonObject>
#include "utilities.h" #include "utilities.h"
#include "version.h"
#ifdef Q_OS_WINDOWS
QString printErrorMessage(DWORD errorCode) {
LPVOID lpMsgBuf;
DWORD dwFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS;
DWORD dwLanguageId = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
FormatMessageW(
dwFlags,
NULL,
errorCode,
dwLanguageId,
(LPWSTR)&lpMsgBuf,
0,
NULL
);
QString errorMsg = QString::fromWCharArray((LPCWSTR)lpMsgBuf);
LocalFree(lpMsgBuf);
return errorMsg.trimmed();
}
QString Utils::getNextDriverLetter()
{
DWORD drivesBitmask = GetLogicalDrives();
if (drivesBitmask == 0) {
DWORD error = GetLastError();
qDebug() << "GetLogicalDrives failed. Error code:" << error;
return "";
}
QString letters = "FGHIJKLMNOPQRSTUVWXYZ";
QString availableLetter;
for (int i = letters.size() - 1; i >= 0; --i) {
QChar letterChar = letters.at(i);
int driveIndex = letterChar.toLatin1() - 'A';
if ((drivesBitmask & (1 << driveIndex)) == 0) {
availableLetter = letterChar;
break;
}
}
if (availableLetter.isEmpty()) {
qDebug() << "Can't find free drive letter";
return "";
}
return availableLetter;
}
#endif
QString Utils::getRandomString(int len) QString Utils::getRandomString(int len)
{ {
const QString possibleCharacters("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); const QString possibleCharacters = QStringLiteral("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
QString randomString; QString randomString;
for (int i = 0; i < len; ++i) { for (int i = 0; i < len; ++i) {
quint32 index = QRandomGenerator::global()->generate() % possibleCharacters.length(); randomString.append(possibleCharacters.at(QRandomGenerator::system()->bounded(possibleCharacters.length())));
QChar nextChar = possibleCharacters.at(index);
randomString.append(nextChar);
} }
return randomString; return randomString;
} }
@ -109,30 +163,34 @@ QString Utils::usrExecutable(const QString &baseName)
bool Utils::processIsRunning(const QString &fileName, const bool fullFlag) bool Utils::processIsRunning(const QString &fileName, const bool fullFlag)
{ {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
QProcess process; HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
process.setReadChannel(QProcess::StandardOutput); if (hSnapshot == INVALID_HANDLE_VALUE) {
process.setProcessChannelMode(QProcess::MergedChannels); qWarning() << "Utils::processIsRunning error CreateToolhelp32Snapshot";
process.start("wmic.exe", return false;
QStringList() << "/OUTPUT:STDOUT" }
<< "PROCESS"
<< "get"
<< "Caption");
process.waitForStarted();
process.waitForFinished();
QString processData(process.readAll());
QStringList processList = processData.split(QRegularExpression("[\r\n]"), Qt::SkipEmptyParts);
foreach (const QString &rawLine, processList) {
const QString line = rawLine.simplified();
if (line.isEmpty()) {
continue;
}
if (line == fileName) { PROCESSENTRY32W pe32;
pe32.dwSize = sizeof(PROCESSENTRY32W);
if (!Process32FirstW(hSnapshot, &pe32)) {
CloseHandle(hSnapshot);
qWarning() << "Utils::processIsRunning error Process32FirstW";
return false;
}
do {
QString exeFile = QString::fromWCharArray(pe32.szExeFile);
if (exeFile.compare(fileName, Qt::CaseInsensitive) == 0) {
CloseHandle(hSnapshot);
return true; return true;
} }
} } while (Process32NextW(hSnapshot, &pe32));
CloseHandle(hSnapshot);
return false; return false;
#elif defined(Q_OS_IOS)
#elif defined(Q_OS_IOS) || defined(Q_OS_ANDROID)
return false; return false;
#else #else
QProcess process; QProcess process;
@ -150,13 +208,45 @@ bool Utils::processIsRunning(const QString &fileName, const bool fullFlag)
#endif #endif
} }
void Utils::killProcessByName(const QString &name) bool Utils::killProcessByName(const QString &name)
{ {
qDebug().noquote() << "Kill process" << name; qDebug().noquote() << "Kill process" << name;
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
QProcess::execute("taskkill", QStringList() << "/IM" << name << "/F"); HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
#elif defined Q_OS_IOS if (hSnapshot == INVALID_HANDLE_VALUE)
return; return false;
PROCESSENTRY32W pe32;
pe32.dwSize = sizeof(PROCESSENTRY32W);
bool success = false;
if (Process32FirstW(hSnapshot, &pe32)) {
do {
QString exeFile = QString::fromWCharArray(pe32.szExeFile);
if (exeFile.compare(name, Qt::CaseInsensitive) == 0) {
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pe32.th32ProcessID);
if (hProcess != NULL) {
if (TerminateProcess(hProcess, 0)) {
success = true;
} else {
DWORD error = GetLastError();
qCritical() << "Can't terminate process" << exeFile << "(PID:" << pe32.th32ProcessID << "). Error:" << printErrorMessage(error);
}
CloseHandle(hProcess);
} else {
DWORD error = GetLastError();
qCritical() << "Can't open process for termination" << exeFile << "(PID:" << pe32.th32ProcessID << "). Error:" << printErrorMessage(error);
}
}
} while (Process32NextW(hSnapshot, &pe32));
}
CloseHandle(hSnapshot);
return success;
#elif defined Q_OS_IOS || defined(Q_OS_ANDROID)
return false;
#else #else
QProcess::execute(QString("pkill %1").arg(name)); QProcess::execute(QString("pkill %1").arg(name));
#endif #endif
@ -244,3 +334,22 @@ bool Utils::signalCtrl(DWORD dwProcessId, DWORD dwCtrlEvent)
} }
#endif #endif
void Utils::logException(const std::exception &e)
{
qCritical() << e.what();
try {
std::rethrow_if_nested(e);
} catch (const std::exception &nested) {
logException(nested);
} catch (...) {}
}
void Utils::logException(const std::exception_ptr &eptr)
{
try {
if (eptr) std::rethrow_exception(eptr);
} catch (const std::exception &e) {
logException(e);
} catch (...) {}
}

9
client/utilities.h Normal file → Executable file
View file

@ -7,7 +7,8 @@
#include <QJsonDocument> #include <QJsonDocument>
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#include "Windows.h" #include <windows.h>
#include <tlhelp32.h>
#endif #endif
class Utils : public QObject class Utils : public QObject
@ -27,15 +28,19 @@ public:
static bool initializePath(const QString &path); static bool initializePath(const QString &path);
static bool processIsRunning(const QString &fileName, const bool fullFlag = false); static bool processIsRunning(const QString &fileName, const bool fullFlag = false);
static void killProcessByName(const QString &name); static bool killProcessByName(const QString &name);
static QString openVpnExecPath(); static QString openVpnExecPath();
static QString wireguardExecPath(); static QString wireguardExecPath();
static QString certUtilPath(); static QString certUtilPath();
static QString tun2socksPath(); static QString tun2socksPath();
static void logException(const std::exception &e);
static void logException(const std::exception_ptr &eptr = std::current_exception());
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
static bool signalCtrl(DWORD dwProcessId, DWORD dwCtrlEvent); static bool signalCtrl(DWORD dwProcessId, DWORD dwCtrlEvent);
static QString getNextDriverLetter();
#endif #endif
}; };

View file

@ -56,14 +56,15 @@ void VpnConnection::onConnectionStateChanged(Vpn::ConnectionState state)
{ {
#ifdef AMNEZIA_DESKTOP #ifdef AMNEZIA_DESKTOP
QString proto = m_settings->defaultContainerName(m_settings->defaultServerIndex()); auto container = m_settings->defaultContainer(m_settings->defaultServerIndex());
if (IpcClient::Interface()) { if (IpcClient::Interface()) {
if (state == Vpn::ConnectionState::Connected) { if (state == Vpn::ConnectionState::Connected) {
IpcClient::Interface()->resetIpStack(); IpcClient::Interface()->resetIpStack();
IpcClient::Interface()->flushDns(); IpcClient::Interface()->flushDns();
if (!m_vpnConfiguration.value(config_key::configVersion).toInt()) { if (!m_vpnConfiguration.value(config_key::configVersion).toInt() && container != DockerContainer::Awg
&& container != DockerContainer::WireGuard) {
QString dns1 = m_vpnConfiguration.value(config_key::dns1).toString(); QString dns1 = m_vpnConfiguration.value(config_key::dns1).toString();
QString dns2 = m_vpnConfiguration.value(config_key::dns2).toString(); QString dns2 = m_vpnConfiguration.value(config_key::dns2).toString();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB