Compare commits
119 Commits
bugfix/fix
...
fixbug/mac
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6971577144 | ||
|
|
a9314b8c8b | ||
|
|
b0ec96cc5b | ||
|
|
a58fea69af | ||
|
|
6c533135cb | ||
|
|
55202f2109 | ||
|
|
b999a7ad97 | ||
|
|
f777ad2650 | ||
|
|
599dad87a7 | ||
|
|
4532a9114f | ||
|
|
e104795610 | ||
|
|
771ef6e951 | ||
|
|
a2de7e0e91 | ||
|
|
7d6e83f977 | ||
|
|
99621310ba | ||
|
|
e7b25719e4 | ||
|
|
7183e8541c | ||
|
|
9e71e64cbd | ||
|
|
4f3bae4a9a | ||
|
|
990059f8a6 | ||
|
|
af55af5e76 | ||
|
|
82d96a9691 | ||
|
|
9f3f215452 | ||
|
|
2dfc6a87b8 | ||
|
|
7261a86c48 | ||
|
|
2946dd2278 | ||
|
|
5065262aac | ||
|
|
4685d3b543 | ||
|
|
7a389e8755 | ||
|
|
4e5daf22a3 | ||
|
|
3bf9c10d7d | ||
|
|
2e175cb9fc | ||
|
|
823c1b5d3a | ||
|
|
92bc1a6f09 | ||
|
|
d511220f8b | ||
|
|
923e358aaa | ||
|
|
92b19eccf6 | ||
|
|
5358aaeb00 | ||
|
|
e31a2066c0 | ||
|
|
928c4f18c9 | ||
|
|
2be5bbcaff | ||
|
|
a6f2e5db3a | ||
|
|
364d4abc47 | ||
|
|
beedfaf808 | ||
|
|
628e22869d | ||
|
|
c9cd860654 | ||
|
|
17984adae5 | ||
|
|
5601bc4fdf | ||
|
|
e14681801e | ||
|
|
f106b4d367 | ||
|
|
74802f30ed | ||
|
|
d63bf15011 | ||
|
|
60de146f03 | ||
|
|
c4f32eed31 | ||
|
|
2c9067b0de | ||
|
|
109057075b | ||
|
|
3dd7351ec9 | ||
|
|
f064b9e2c4 | ||
|
|
5747eaf5bc | ||
|
|
d63bab3113 | ||
|
|
a33da4058d | ||
|
|
d4f9acdb94 | ||
|
|
6844a2375b | ||
|
|
7b838e77a0 | ||
|
|
bfbcb64f46 | ||
|
|
3721d64a72 | ||
|
|
26589d255f | ||
|
|
d0b85813c7 | ||
|
|
484d33e922 | ||
|
|
b3cd6e03a2 | ||
|
|
1cdb8b33ee | ||
|
|
e4679ff1fb | ||
|
|
6ef03f9374 | ||
|
|
e6c3ece85c | ||
|
|
f8b951a428 | ||
|
|
ea1a7e8701 | ||
|
|
4700947fcb | ||
|
|
e1d23c6738 | ||
|
|
694e781beb | ||
|
|
399a8c6d28 | ||
|
|
bfc2ac6c32 | ||
|
|
9fc1df38cc | ||
|
|
336850624f | ||
|
|
4287e5aa76 | ||
|
|
c9b61f48cf | ||
|
|
4c9a249695 | ||
|
|
d0db1293b5 | ||
|
|
aaa8030348 | ||
|
|
3c3d4252f2 | ||
|
|
56d6ab2dd5 | ||
|
|
b93c5f3e57 | ||
|
|
9ddfa54352 | ||
|
|
1e893c2260 | ||
|
|
7d186c3c84 | ||
|
|
31938899a2 | ||
|
|
b338a4fb79 | ||
|
|
0500f1887c | ||
|
|
226f9b9316 | ||
|
|
ae16b19515 | ||
|
|
5569524efa | ||
|
|
e2099b1682 | ||
|
|
022444ad63 | ||
|
|
7da585fc27 | ||
|
|
b1ad874f14 | ||
|
|
dce08b3ecc | ||
|
|
f7aa82331e | ||
|
|
b6601d051a | ||
|
|
1e60792f0c | ||
|
|
2763da960f | ||
|
|
d4fff4af3c | ||
|
|
f0903c32f3 | ||
|
|
ea8875478e | ||
|
|
4c08e9f3bc | ||
|
|
e8736102bf | ||
|
|
371cadcc02 | ||
|
|
02a98b9d68 | ||
|
|
1542adba82 | ||
|
|
3aa8a46f6e | ||
|
|
1f08d78b43 |
83
.github/workflows/deploy.yml
vendored
@@ -16,7 +16,10 @@ jobs:
|
||||
QT_VERSION: 6.6.2
|
||||
QIF_VERSION: 4.7
|
||||
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_ENDPOINT: ${{ secrets.DEV_AGW_ENDPOINT }}
|
||||
DEV_S3_ENDPOINT: ${{ secrets.DEV_S3_ENDPOINT }}
|
||||
|
||||
steps:
|
||||
- name: 'Install Qt'
|
||||
@@ -83,7 +86,10 @@ jobs:
|
||||
QIF_VERSION: 4.7
|
||||
BUILD_ARCH: 64
|
||||
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_ENDPOINT: ${{ secrets.DEV_AGW_ENDPOINT }}
|
||||
DEV_S3_ENDPOINT: ${{ secrets.DEV_S3_ENDPOINT }}
|
||||
|
||||
steps:
|
||||
- name: 'Get sources'
|
||||
@@ -146,7 +152,10 @@ jobs:
|
||||
CC: cc
|
||||
CXX: c++
|
||||
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_ENDPOINT: ${{ secrets.DEV_AGW_ENDPOINT }}
|
||||
DEV_S3_ENDPOINT: ${{ secrets.DEV_S3_ENDPOINT }}
|
||||
|
||||
steps:
|
||||
- name: 'Setup xcode'
|
||||
@@ -238,7 +247,10 @@ jobs:
|
||||
QT_VERSION: 6.4.3
|
||||
QIF_VERSION: 4.6
|
||||
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_ENDPOINT: ${{ secrets.DEV_AGW_ENDPOINT }}
|
||||
DEV_S3_ENDPOINT: ${{ secrets.DEV_S3_ENDPOINT }}
|
||||
|
||||
steps:
|
||||
- name: 'Setup xcode'
|
||||
@@ -294,6 +306,70 @@ jobs:
|
||||
path: deploy/build/client/AmneziaVPN.app
|
||||
retention-days: 7
|
||||
|
||||
# ------------------------------------------------------
|
||||
Build-MacOS-NE:
|
||||
runs-on: macos-latest
|
||||
|
||||
env:
|
||||
QT_VERSION: 6.4.3
|
||||
QIF_VERSION: 4.6
|
||||
QT_MIRROR: https://mirrors.ocf.berkeley.edu/qt/
|
||||
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
|
||||
DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }}
|
||||
|
||||
steps:
|
||||
- name: 'Setup Xcode'
|
||||
uses: maxim-lobanov/setup-xcode@v1
|
||||
with:
|
||||
xcode-version: '14.3.1'
|
||||
|
||||
- name: 'Install desktop Qt'
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
host: 'mac'
|
||||
target: 'desktop'
|
||||
modules: 'qtremoteobjects qt5compat qtshadertools qtmultimedia'
|
||||
arch: 'clang_64'
|
||||
dir: ${{ runner.temp }}
|
||||
set-env: 'true'
|
||||
extra: '--base ${{ env.QT_MIRROR }}'
|
||||
- name: 'Install Qt Installer Framework ${{ env.QIF_VERSION }}'
|
||||
run: |
|
||||
mkdir -pv ${{ runner.temp }}/Qt/Tools/QtInstallerFramework
|
||||
wget https://qt.amzsvc.com/tools/ifw/${{ env.QIF_VERSION }}.zip
|
||||
unzip ${{ env.QIF_VERSION }}.zip -d ${{ runner.temp }}/Qt/Tools/QtInstallerFramework/
|
||||
- name: 'Install Go'
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.22.1'
|
||||
cache: false
|
||||
|
||||
- name: 'Get sources'
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: 'true'
|
||||
fetch-depth: 10
|
||||
|
||||
- name: 'Install dependencies'
|
||||
run: pip install jsonschema jinja2
|
||||
|
||||
- name: 'Set execute permissions for deploy script'
|
||||
run: chmod +x deploy/build_macos_ne.sh
|
||||
|
||||
# - name: 'Build and deploy macOS NE'
|
||||
# run: |
|
||||
# export QT_BIN_DIR="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/macos/bin"
|
||||
# export QIF_BIN_DIR="${{ runner.temp }}/Qt/Tools/QtInstallerFramework/${{ env.QIF_VERSION }}/bin"
|
||||
# export QT_MACOS_ROOT_DIR="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/macos"
|
||||
# bash deploy/build_macos_ne.sh
|
||||
# env:
|
||||
# APPSTORE_CONNECT_KEY_ID: ${{ secrets.APPSTORE_CONNECT_KEY_ID }}
|
||||
# APPSTORE_CONNECT_ISSUER_ID: ${{ secrets.APPSTORE_CONNECT_ISSUER_ID }}
|
||||
# APPSTORE_CONNECT_PRIVATE_KEY: ${{ secrets.APPSTORE_CONNECT_PRIVATE_KEY }}
|
||||
# MAC_TRUST_CERT_BASE64: ${{ secrets.IOS_TRUST_CERT_BASE64 }}
|
||||
# MAC_SIGNING_CERT_BASE64: ${{ secrets.IOS_SIGNING_CERT_BASE64 }}
|
||||
# MAC_SIGNING_CERT_PASSWORD: ${{ secrets.IOS_SIGNING_CERT_PASSWORD }}
|
||||
# ------------------------------------------------------
|
||||
|
||||
Build-Android:
|
||||
@@ -301,10 +377,13 @@ jobs:
|
||||
|
||||
env:
|
||||
ANDROID_BUILD_PLATFORM: android-34
|
||||
QT_VERSION: 6.7.2
|
||||
QT_VERSION: 6.7.3
|
||||
QT_MODULES: 'qtremoteobjects qt5compat qtimageformats qtshadertools'
|
||||
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_ENDPOINT: ${{ secrets.DEV_AGW_ENDPOINT }}
|
||||
DEV_S3_ENDPOINT: ${{ secrets.DEV_S3_ENDPOINT }}
|
||||
|
||||
steps:
|
||||
- name: 'Install desktop Qt'
|
||||
@@ -461,4 +540,4 @@ jobs:
|
||||
if: ${{ fromJSON(steps.pull_request.outputs.data)[0].number != '' }}
|
||||
run: |
|
||||
echo "Pull request:" >> $GITHUB_STEP_SUMMARY
|
||||
echo "[[#${{ fromJSON(steps.pull_request.outputs.data)[0].number }}] ${{ fromJSON(steps.pull_request.outputs.data)[0].title }}](${{ fromJSON(steps.pull_request.outputs.data)[0].html_url }})" >> $GITHUB_STEP_SUMMARY
|
||||
echo "[[#${{ fromJSON(steps.pull_request.outputs.data)[0].number }}] ${{ fromJSON(steps.pull_request.outputs.data)[0].title }}](${{ fromJSON(steps.pull_request.outputs.data)[0].html_url }})" >> $GITHUB_STEP_SUMMARY
|
||||
3
.github/workflows/tag-deploy.yml
vendored
@@ -16,7 +16,10 @@ jobs:
|
||||
QT_VERSION: 6.4.1
|
||||
QIF_VERSION: 4.5
|
||||
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_ENDPOINT: ${{ secrets.DEV_AGW_ENDPOINT }}
|
||||
DEV_S3_ENDPOINT: ${{ secrets.DEV_S3_ENDPOINT }}
|
||||
|
||||
steps:
|
||||
- name: 'Install desktop Qt'
|
||||
|
||||
2
.gitmodules
vendored
@@ -1,6 +1,7 @@
|
||||
[submodule "client/3rd/OpenVPNAdapter"]
|
||||
path = client/3rd/OpenVPNAdapter
|
||||
url = https://github.com/amnezia-vpn/OpenVPNAdapter.git
|
||||
branch = macos-dirty-build
|
||||
[submodule "client/3rd/qtkeychain"]
|
||||
path = client/3rd/qtkeychain
|
||||
url = https://github.com/frankosterfeld/qtkeychain.git
|
||||
@@ -10,6 +11,7 @@
|
||||
[submodule "client/3rd-prebuilt"]
|
||||
path = client/3rd-prebuilt
|
||||
url = https://github.com/amnezia-vpn/3rd-prebuilt
|
||||
branch = fixbug/mac-network-extension
|
||||
[submodule "client/3rd/amneziawg-apple"]
|
||||
path = client/3rd/amneziawg-apple
|
||||
url = https://github.com/amnezia-vpn/amneziawg-apple
|
||||
|
||||
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR)
|
||||
|
||||
set(PROJECT AmneziaVPN)
|
||||
|
||||
project(${PROJECT} VERSION 4.8.1.8
|
||||
project(${PROJECT} VERSION 4.8.2.3
|
||||
DESCRIPTION "AmneziaVPN"
|
||||
HOMEPAGE_URL "https://amnezia.org/"
|
||||
)
|
||||
@@ -11,7 +11,7 @@ string(TIMESTAMP CURRENT_DATE "%Y-%m-%d")
|
||||
set(RELEASE_DATE "${CURRENT_DATE}")
|
||||
|
||||
set(APP_MAJOR_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
|
||||
set(APP_ANDROID_VERSION_CODE 63)
|
||||
set(APP_ANDROID_VERSION_CODE 2069)
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
set(MZ_PLATFORM_NAME "linux")
|
||||
@@ -31,13 +31,13 @@ set(QT_BUILD_TOOLS_WHEN_CROSS_COMPILING ON)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
if(APPLE AND NOT IOS)
|
||||
if((APPLE AND NOT IOS) OR (DEFINED MACOS_NE AND MACOS_NE AND NOT IOS))
|
||||
set(CMAKE_OSX_ARCHITECTURES "x86_64")
|
||||
endif()
|
||||
|
||||
add_subdirectory(client)
|
||||
|
||||
if(NOT IOS AND NOT ANDROID)
|
||||
if(NOT IOS AND NOT ANDROID AND NOT MACOS_NE)
|
||||
add_subdirectory(service)
|
||||
|
||||
include(${CMAKE_SOURCE_DIR}/deploy/installer/config.cmake)
|
||||
|
||||
12
README.md
@@ -10,21 +10,17 @@ Amnezia is an open-source VPN client, with a key feature that enables you to dep
|
||||
|
||||
<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://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://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://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>
|
||||
|
||||
[Alternative download link (mirror)](https://storage.googleapis.com/kldscp/amnezia.org/downloads)
|
||||
|
||||
[All releases](https://github.com/amnezia-vpn/amnezia-client/releases)
|
||||
|
||||
<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
|
||||
|
||||
@@ -37,7 +33,7 @@ Amnezia is an open-source VPN client, with a key feature that enables you to dep
|
||||
|
||||
## 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://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)
|
||||
|
||||
2
client/3rd/OpenVPNAdapter
vendored
@@ -1,25 +0,0 @@
|
||||
include_directories(${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS
|
||||
Core Network
|
||||
)
|
||||
set(LIBS ${LIBS} Qt6::Core Qt6::Network)
|
||||
|
||||
|
||||
set(HEADERS ${HEADERS}
|
||||
${CMAKE_CURRENT_LIST_DIR}/singleapplication.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/singleapplication_p.h
|
||||
)
|
||||
|
||||
set(SOURCES ${SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/singleapplication.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/singleapplication_p.cpp
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
if(MSVC)
|
||||
set(LIBS ${LIBS} Advapi32.lib)
|
||||
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
set(LIBS ${LIBS} advapi32)
|
||||
endif()
|
||||
endif()
|
||||
@@ -1,274 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) Itay Grudev 2015 - 2020
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include <QtCore/QElapsedTimer>
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QSharedMemory>
|
||||
|
||||
#include "singleapplication.h"
|
||||
#include "singleapplication_p.h"
|
||||
|
||||
/**
|
||||
* @brief Constructor. Checks and fires up LocalServer or closes the program
|
||||
* if another instance already exists
|
||||
* @param argc
|
||||
* @param argv
|
||||
* @param allowSecondary Whether to enable secondary instance support
|
||||
* @param options Optional flags to toggle specific behaviour
|
||||
* @param timeout Maximum time blocking functions are allowed during app load
|
||||
*/
|
||||
SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSecondary, Options options, int timeout, const QString &userData )
|
||||
: app_t( argc, argv ), d_ptr( new SingleApplicationPrivate( this ) )
|
||||
{
|
||||
Q_D( SingleApplication );
|
||||
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||
// On Android and iOS since the library is not supported fallback to
|
||||
// standard QApplication behaviour by simply returning at this point.
|
||||
qWarning() << "SingleApplication is not supported on Android and iOS systems.";
|
||||
return;
|
||||
#endif
|
||||
|
||||
// Store the current mode of the program
|
||||
d->options = options;
|
||||
|
||||
// Add any unique user data
|
||||
if ( ! userData.isEmpty() )
|
||||
d->addAppData( userData );
|
||||
|
||||
// Generating an application ID used for identifying the shared memory
|
||||
// block and QLocalServer
|
||||
d->genBlockServerName();
|
||||
|
||||
// To mitigate QSharedMemory issues with large amount of processes
|
||||
// attempting to attach at the same time
|
||||
SingleApplicationPrivate::randomSleep();
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
// By explicitly attaching it and then deleting it we make sure that the
|
||||
// memory is deleted even after the process has crashed on Unix.
|
||||
d->memory = new QSharedMemory( d->blockServerName );
|
||||
d->memory->attach();
|
||||
delete d->memory;
|
||||
#endif
|
||||
// Guarantee thread safe behaviour with a shared memory block.
|
||||
d->memory = new QSharedMemory( d->blockServerName );
|
||||
|
||||
// Create a shared memory block
|
||||
if( d->memory->create( sizeof( InstancesInfo ) )){
|
||||
// Initialize the shared memory block
|
||||
if( ! d->memory->lock() ){
|
||||
qCritical() << "SingleApplication: Unable to lock memory block after create.";
|
||||
abortSafely();
|
||||
}
|
||||
d->initializeMemoryBlock();
|
||||
} else {
|
||||
if( d->memory->error() == QSharedMemory::AlreadyExists ){
|
||||
// Attempt to attach to the memory segment
|
||||
if( ! d->memory->attach() ){
|
||||
qCritical() << "SingleApplication: Unable to attach to shared memory block.";
|
||||
abortSafely();
|
||||
}
|
||||
if( ! d->memory->lock() ){
|
||||
qCritical() << "SingleApplication: Unable to lock memory block after attach.";
|
||||
abortSafely();
|
||||
}
|
||||
} else {
|
||||
qCritical() << "SingleApplication: Unable to create block.";
|
||||
abortSafely();
|
||||
}
|
||||
}
|
||||
|
||||
auto *inst = static_cast<InstancesInfo*>( d->memory->data() );
|
||||
QElapsedTimer time;
|
||||
time.start();
|
||||
|
||||
// Make sure the shared memory block is initialised and in consistent state
|
||||
while( true ){
|
||||
// If the shared memory block's checksum is valid continue
|
||||
if( d->blockChecksum() == inst->checksum ) break;
|
||||
|
||||
// If more than 5s have elapsed, assume the primary instance crashed and
|
||||
// assume it's position
|
||||
if( time.elapsed() > 5000 ){
|
||||
qWarning() << "SingleApplication: Shared memory block has been in an inconsistent state from more than 5s. Assuming primary instance failure.";
|
||||
d->initializeMemoryBlock();
|
||||
}
|
||||
|
||||
// Otherwise wait for a random period and try again. The random sleep here
|
||||
// limits the probability of a collision between two racing apps and
|
||||
// allows the app to initialise faster
|
||||
if( ! d->memory->unlock() ){
|
||||
qDebug() << "SingleApplication: Unable to unlock memory for random wait.";
|
||||
qDebug() << d->memory->errorString();
|
||||
}
|
||||
SingleApplicationPrivate::randomSleep();
|
||||
if( ! d->memory->lock() ){
|
||||
qCritical() << "SingleApplication: Unable to lock memory after random wait.";
|
||||
abortSafely();
|
||||
}
|
||||
}
|
||||
|
||||
if( inst->primary == false ){
|
||||
d->startPrimary();
|
||||
if( ! d->memory->unlock() ){
|
||||
qDebug() << "SingleApplication: Unable to unlock memory after primary start.";
|
||||
qDebug() << d->memory->errorString();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if another instance can be started
|
||||
if( allowSecondary ){
|
||||
d->startSecondary();
|
||||
if( d->options & Mode::SecondaryNotification ){
|
||||
d->connectToPrimary( timeout, SingleApplicationPrivate::SecondaryInstance );
|
||||
}
|
||||
if( ! d->memory->unlock() ){
|
||||
qDebug() << "SingleApplication: Unable to unlock memory after secondary start.";
|
||||
qDebug() << d->memory->errorString();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if( ! d->memory->unlock() ){
|
||||
qDebug() << "SingleApplication: Unable to unlock memory at end of execution.";
|
||||
qDebug() << d->memory->errorString();
|
||||
}
|
||||
|
||||
d->connectToPrimary( timeout, SingleApplicationPrivate::NewInstance );
|
||||
|
||||
delete d;
|
||||
|
||||
::exit( EXIT_SUCCESS );
|
||||
}
|
||||
|
||||
SingleApplication::~SingleApplication()
|
||||
{
|
||||
Q_D( SingleApplication );
|
||||
delete d;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current application instance is primary.
|
||||
* @return Returns true if the instance is primary, false otherwise.
|
||||
*/
|
||||
bool SingleApplication::isPrimary() const
|
||||
{
|
||||
Q_D( const SingleApplication );
|
||||
return d->server != nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current application instance is secondary.
|
||||
* @return Returns true if the instance is secondary, false otherwise.
|
||||
*/
|
||||
bool SingleApplication::isSecondary() const
|
||||
{
|
||||
Q_D( const SingleApplication );
|
||||
return d->server == nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows you to identify an instance by returning unique consecutive instance
|
||||
* ids. It is reset when the first (primary) instance of your app starts and
|
||||
* only incremented afterwards.
|
||||
* @return Returns a unique instance id.
|
||||
*/
|
||||
quint32 SingleApplication::instanceId() const
|
||||
{
|
||||
Q_D( const SingleApplication );
|
||||
return d->instanceNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the OS PID (Process Identifier) of the process running the primary
|
||||
* instance. Especially useful when SingleApplication is coupled with OS.
|
||||
* specific APIs.
|
||||
* @return Returns the primary instance PID.
|
||||
*/
|
||||
qint64 SingleApplication::primaryPid() const
|
||||
{
|
||||
Q_D( const SingleApplication );
|
||||
return d->primaryPid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the username the primary instance is running as.
|
||||
* @return Returns the username the primary instance is running as.
|
||||
*/
|
||||
QString SingleApplication::primaryUser() const
|
||||
{
|
||||
Q_D( const SingleApplication );
|
||||
return d->primaryUser();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the username the current instance is running as.
|
||||
* @return Returns the username the current instance is running as.
|
||||
*/
|
||||
QString SingleApplication::currentUser() const
|
||||
{
|
||||
return SingleApplicationPrivate::getUsername();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends message to the Primary Instance.
|
||||
* @param message The message to send.
|
||||
* @param timeout the maximum timeout in milliseconds for blocking functions.
|
||||
* @return true if the message was sent successfuly, false otherwise.
|
||||
*/
|
||||
bool SingleApplication::sendMessage( const QByteArray &message, int timeout )
|
||||
{
|
||||
Q_D( SingleApplication );
|
||||
|
||||
// Nobody to connect to
|
||||
if( isPrimary() ) return false;
|
||||
|
||||
// Make sure the socket is connected
|
||||
if( ! d->connectToPrimary( timeout, SingleApplicationPrivate::Reconnect ) )
|
||||
return false;
|
||||
|
||||
d->socket->write( message );
|
||||
bool dataWritten = d->socket->waitForBytesWritten( timeout );
|
||||
d->socket->flush();
|
||||
return dataWritten;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up the shared memory block and exits with a failure.
|
||||
* This function halts program execution.
|
||||
*/
|
||||
void SingleApplication::abortSafely()
|
||||
{
|
||||
Q_D( SingleApplication );
|
||||
|
||||
qCritical() << "SingleApplication: " << d->memory->error() << d->memory->errorString();
|
||||
delete d;
|
||||
::exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
QStringList SingleApplication::userData() const
|
||||
{
|
||||
Q_D( const SingleApplication );
|
||||
return d->appData();
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) Itay Grudev 2015 - 2018
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef SINGLE_APPLICATION_H
|
||||
#define SINGLE_APPLICATION_H
|
||||
|
||||
#include <QtCore/QtGlobal>
|
||||
#include <QtNetwork/QLocalSocket>
|
||||
|
||||
#ifndef QAPPLICATION_CLASS
|
||||
#define QAPPLICATION_CLASS QApplication
|
||||
#endif
|
||||
|
||||
#include QT_STRINGIFY(QAPPLICATION_CLASS)
|
||||
|
||||
class SingleApplicationPrivate;
|
||||
|
||||
/**
|
||||
* @brief The SingleApplication class handles multiple instances of the same
|
||||
* Application
|
||||
* @see QCoreApplication
|
||||
*/
|
||||
class SingleApplication : public QAPPLICATION_CLASS
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using app_t = QAPPLICATION_CLASS;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Mode of operation of SingleApplication.
|
||||
* Whether the block should be user-wide or system-wide and whether the
|
||||
* primary instance should be notified when a secondary instance had been
|
||||
* started.
|
||||
* @note Operating system can restrict the shared memory blocks to the same
|
||||
* user, in which case the User/System modes will have no effect and the
|
||||
* block will be user wide.
|
||||
* @enum
|
||||
*/
|
||||
enum Mode {
|
||||
User = 1 << 0,
|
||||
System = 1 << 1,
|
||||
SecondaryNotification = 1 << 2,
|
||||
ExcludeAppVersion = 1 << 3,
|
||||
ExcludeAppPath = 1 << 4
|
||||
};
|
||||
Q_DECLARE_FLAGS(Options, Mode)
|
||||
|
||||
/**
|
||||
* @brief Intitializes a SingleApplication instance with argc command line
|
||||
* arguments in argv
|
||||
* @arg {int &} argc - Number of arguments in argv
|
||||
* @arg {const char *[]} argv - Supplied command line arguments
|
||||
* @arg {bool} allowSecondary - Whether to start the instance as secondary
|
||||
* if there is already a primary instance.
|
||||
* @arg {Mode} mode - Whether for the SingleApplication block to be applied
|
||||
* User wide or System wide.
|
||||
* @arg {int} timeout - Timeout to wait in milliseconds.
|
||||
* @note argc and argv may be changed as Qt removes arguments that it
|
||||
* recognizes
|
||||
* @note Mode::SecondaryNotification only works if set on both the primary
|
||||
* instance and the secondary instance.
|
||||
* @note The timeout is just a hint for the maximum time of blocking
|
||||
* operations. It does not guarantee that the SingleApplication
|
||||
* initialisation will be completed in given time, though is a good hint.
|
||||
* Usually 4*timeout would be the worst case (fail) scenario.
|
||||
* @see See the corresponding QAPPLICATION_CLASS constructor for reference
|
||||
*/
|
||||
explicit SingleApplication( int &argc, char *argv[], bool allowSecondary = false, Options options = Mode::User, int timeout = 1000, const QString &userData = {} );
|
||||
~SingleApplication() override;
|
||||
|
||||
/**
|
||||
* @brief Returns if the instance is the primary instance
|
||||
* @returns {bool}
|
||||
*/
|
||||
bool isPrimary() const;
|
||||
|
||||
/**
|
||||
* @brief Returns if the instance is a secondary instance
|
||||
* @returns {bool}
|
||||
*/
|
||||
bool isSecondary() const;
|
||||
|
||||
/**
|
||||
* @brief Returns a unique identifier for the current instance
|
||||
* @returns {qint32}
|
||||
*/
|
||||
quint32 instanceId() const;
|
||||
|
||||
/**
|
||||
* @brief Returns the process ID (PID) of the primary instance
|
||||
* @returns {qint64}
|
||||
*/
|
||||
qint64 primaryPid() const;
|
||||
|
||||
/**
|
||||
* @brief Returns the username of the user running the primary instance
|
||||
* @returns {QString}
|
||||
*/
|
||||
QString primaryUser() const;
|
||||
|
||||
/**
|
||||
* @brief Returns the username of the current user
|
||||
* @returns {QString}
|
||||
*/
|
||||
QString currentUser() const;
|
||||
|
||||
/**
|
||||
* @brief Sends a message to the primary instance. Returns true on success.
|
||||
* @param {int} timeout - Timeout for connecting
|
||||
* @returns {bool}
|
||||
* @note sendMessage() will return false if invoked from the primary
|
||||
* instance.
|
||||
*/
|
||||
bool sendMessage( const QByteArray &message, int timeout = 100 );
|
||||
|
||||
/**
|
||||
* @brief Get the set user data.
|
||||
* @returns {QStringList}
|
||||
*/
|
||||
QStringList userData() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void instanceStarted();
|
||||
void receivedMessage( quint32 instanceId, QByteArray message );
|
||||
|
||||
private:
|
||||
SingleApplicationPrivate *d_ptr;
|
||||
Q_DECLARE_PRIVATE(SingleApplication)
|
||||
void abortSafely();
|
||||
};
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(SingleApplication::Options)
|
||||
|
||||
#endif // SINGLE_APPLICATION_H
|
||||
@@ -1,15 +0,0 @@
|
||||
QT += core network
|
||||
CONFIG += c++11
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/singleapplication.h \
|
||||
$$PWD/singleapplication_p.h
|
||||
SOURCES += $$PWD/singleapplication.cpp \
|
||||
$$PWD/singleapplication_p.cpp
|
||||
|
||||
INCLUDEPATH += $$PWD
|
||||
|
||||
win32 {
|
||||
msvc:LIBS += Advapi32.lib
|
||||
gcc:LIBS += -ladvapi32
|
||||
}
|
||||
@@ -1,486 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) Itay Grudev 2015 - 2020
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
//
|
||||
// W A R N I N G !!!
|
||||
// -----------------
|
||||
//
|
||||
// This file is not part of the SingleApplication API. It is used purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or may even be removed.
|
||||
//
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QThread>
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QDataStream>
|
||||
#include <QtCore/QElapsedTimer>
|
||||
#include <QtCore/QCryptographicHash>
|
||||
#include <QtNetwork/QLocalServer>
|
||||
#include <QtNetwork/QLocalSocket>
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
|
||||
#include <QtCore/QRandomGenerator>
|
||||
#else
|
||||
#include <QtCore/QDateTime>
|
||||
#endif
|
||||
|
||||
#include "singleapplication.h"
|
||||
#include "singleapplication_p.h"
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX 1
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <lmcons.h>
|
||||
#endif
|
||||
|
||||
SingleApplicationPrivate::SingleApplicationPrivate( SingleApplication *q_ptr )
|
||||
: q_ptr( q_ptr )
|
||||
{
|
||||
server = nullptr;
|
||||
socket = nullptr;
|
||||
memory = nullptr;
|
||||
instanceNumber = 0;
|
||||
}
|
||||
|
||||
SingleApplicationPrivate::~SingleApplicationPrivate()
|
||||
{
|
||||
if( socket != nullptr ){
|
||||
socket->close();
|
||||
delete socket;
|
||||
}
|
||||
|
||||
if( memory != nullptr ){
|
||||
memory->lock();
|
||||
auto *inst = static_cast<InstancesInfo*>(memory->data());
|
||||
if( server != nullptr ){
|
||||
server->close();
|
||||
delete server;
|
||||
inst->primary = false;
|
||||
inst->primaryPid = -1;
|
||||
inst->primaryUser[0] = '\0';
|
||||
inst->checksum = blockChecksum();
|
||||
}
|
||||
memory->unlock();
|
||||
|
||||
delete memory;
|
||||
}
|
||||
}
|
||||
|
||||
QString SingleApplicationPrivate::getUsername()
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
wchar_t username[UNLEN + 1];
|
||||
// Specifies size of the buffer on input
|
||||
DWORD usernameLength = UNLEN + 1;
|
||||
if( GetUserNameW( username, &usernameLength ) )
|
||||
return QString::fromWCharArray( username );
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
|
||||
return QString::fromLocal8Bit( qgetenv( "USERNAME" ) );
|
||||
#else
|
||||
return qEnvironmentVariable( "USERNAME" );
|
||||
#endif
|
||||
#endif
|
||||
#ifdef Q_OS_UNIX
|
||||
QString username;
|
||||
uid_t uid = geteuid();
|
||||
struct passwd *pw = getpwuid( uid );
|
||||
if( pw )
|
||||
username = QString::fromLocal8Bit( pw->pw_name );
|
||||
if ( username.isEmpty() ){
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
|
||||
username = QString::fromLocal8Bit( qgetenv( "USER" ) );
|
||||
#else
|
||||
username = qEnvironmentVariable( "USER" );
|
||||
#endif
|
||||
}
|
||||
return username;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::genBlockServerName()
|
||||
{
|
||||
QCryptographicHash appData( QCryptographicHash::Sha256 );
|
||||
appData.addData( "SingleApplication", 17 );
|
||||
appData.addData( SingleApplication::app_t::applicationName().toUtf8() );
|
||||
appData.addData( SingleApplication::app_t::organizationName().toUtf8() );
|
||||
appData.addData( SingleApplication::app_t::organizationDomain().toUtf8() );
|
||||
|
||||
if ( ! appDataList.isEmpty() )
|
||||
appData.addData( appDataList.join( "" ).toUtf8() );
|
||||
|
||||
if( ! (options & SingleApplication::Mode::ExcludeAppVersion) ){
|
||||
appData.addData( SingleApplication::app_t::applicationVersion().toUtf8() );
|
||||
}
|
||||
|
||||
if( ! (options & SingleApplication::Mode::ExcludeAppPath) ){
|
||||
#ifdef Q_OS_WIN
|
||||
appData.addData( SingleApplication::app_t::applicationFilePath().toLower().toUtf8() );
|
||||
#else
|
||||
appData.addData( SingleApplication::app_t::applicationFilePath().toUtf8() );
|
||||
#endif
|
||||
}
|
||||
|
||||
// User level block requires a user specific data in the hash
|
||||
if( options & SingleApplication::Mode::User ){
|
||||
appData.addData( getUsername().toUtf8() );
|
||||
}
|
||||
|
||||
// Replace the backslash in RFC 2045 Base64 [a-zA-Z0-9+/=] to comply with
|
||||
// server naming requirements.
|
||||
blockServerName = appData.result().toBase64().replace("/", "_");
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::initializeMemoryBlock() const
|
||||
{
|
||||
auto *inst = static_cast<InstancesInfo*>( memory->data() );
|
||||
inst->primary = false;
|
||||
inst->secondary = 0;
|
||||
inst->primaryPid = -1;
|
||||
inst->primaryUser[0] = '\0';
|
||||
inst->checksum = blockChecksum();
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::startPrimary()
|
||||
{
|
||||
// Reset the number of connections
|
||||
auto *inst = static_cast <InstancesInfo*>( memory->data() );
|
||||
|
||||
inst->primary = true;
|
||||
inst->primaryPid = QCoreApplication::applicationPid();
|
||||
qstrncpy( inst->primaryUser, getUsername().toUtf8().data(), sizeof(inst->primaryUser) );
|
||||
inst->checksum = blockChecksum();
|
||||
instanceNumber = 0;
|
||||
// Successful creation means that no main process exists
|
||||
// So we start a QLocalServer to listen for connections
|
||||
QLocalServer::removeServer( blockServerName );
|
||||
server = new QLocalServer();
|
||||
|
||||
// Restrict access to the socket according to the
|
||||
// SingleApplication::Mode::User flag on User level or no restrictions
|
||||
if( options & SingleApplication::Mode::User ){
|
||||
server->setSocketOptions( QLocalServer::UserAccessOption );
|
||||
} else {
|
||||
server->setSocketOptions( QLocalServer::WorldAccessOption );
|
||||
}
|
||||
|
||||
server->listen( blockServerName );
|
||||
QObject::connect(
|
||||
server,
|
||||
&QLocalServer::newConnection,
|
||||
this,
|
||||
&SingleApplicationPrivate::slotConnectionEstablished
|
||||
);
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::startSecondary()
|
||||
{
|
||||
auto *inst = static_cast <InstancesInfo*>( memory->data() );
|
||||
|
||||
inst->secondary += 1;
|
||||
inst->checksum = blockChecksum();
|
||||
instanceNumber = inst->secondary;
|
||||
}
|
||||
|
||||
bool SingleApplicationPrivate::connectToPrimary( int msecs, ConnectionType connectionType )
|
||||
{
|
||||
QElapsedTimer time;
|
||||
time.start();
|
||||
|
||||
// Connect to the Local Server of the Primary Instance if not already
|
||||
// connected.
|
||||
if( socket == nullptr ){
|
||||
socket = new QLocalSocket();
|
||||
}
|
||||
|
||||
if( socket->state() == QLocalSocket::ConnectedState ) return true;
|
||||
|
||||
if( socket->state() != QLocalSocket::ConnectedState ){
|
||||
|
||||
while( true ){
|
||||
randomSleep();
|
||||
|
||||
if( socket->state() != QLocalSocket::ConnectingState )
|
||||
socket->connectToServer( blockServerName );
|
||||
|
||||
if( socket->state() == QLocalSocket::ConnectingState ){
|
||||
socket->waitForConnected( static_cast<int>(msecs - time.elapsed()) );
|
||||
}
|
||||
|
||||
// If connected break out of the loop
|
||||
if( socket->state() == QLocalSocket::ConnectedState ) break;
|
||||
|
||||
// If elapsed time since start is longer than the method timeout return
|
||||
if( time.elapsed() >= msecs ) return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialisation message according to the SingleApplication protocol
|
||||
QByteArray initMsg;
|
||||
QDataStream writeStream(&initMsg, QIODevice::WriteOnly);
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
|
||||
writeStream.setVersion(QDataStream::Qt_5_6);
|
||||
#endif
|
||||
|
||||
writeStream << blockServerName.toLatin1();
|
||||
writeStream << static_cast<quint8>(connectionType);
|
||||
writeStream << instanceNumber;
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
quint16 checksum = qChecksum(QByteArray(initMsg, static_cast<quint32>(initMsg.length())));
|
||||
#else
|
||||
quint16 checksum = qChecksum(initMsg.constData(), static_cast<quint32>(initMsg.length()));
|
||||
#endif
|
||||
writeStream << checksum;
|
||||
|
||||
// The header indicates the message length that follows
|
||||
QByteArray header;
|
||||
QDataStream headerStream(&header, QIODevice::WriteOnly);
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
|
||||
headerStream.setVersion(QDataStream::Qt_5_6);
|
||||
#endif
|
||||
headerStream << static_cast <quint64>( initMsg.length() );
|
||||
|
||||
socket->write( header );
|
||||
socket->write( initMsg );
|
||||
bool result = socket->waitForBytesWritten( static_cast<int>(msecs - time.elapsed()) );
|
||||
socket->flush();
|
||||
return result;
|
||||
}
|
||||
|
||||
quint16 SingleApplicationPrivate::blockChecksum() const
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
quint16 checksum = qChecksum(QByteArray(static_cast<const char*>(memory->constData()), offsetof(InstancesInfo, checksum)));
|
||||
#else
|
||||
quint16 checksum = qChecksum(static_cast<const char*>(memory->constData()), offsetof(InstancesInfo, checksum));
|
||||
#endif
|
||||
return checksum;
|
||||
}
|
||||
|
||||
qint64 SingleApplicationPrivate::primaryPid() const
|
||||
{
|
||||
qint64 pid;
|
||||
|
||||
memory->lock();
|
||||
auto *inst = static_cast<InstancesInfo*>( memory->data() );
|
||||
pid = inst->primaryPid;
|
||||
memory->unlock();
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
QString SingleApplicationPrivate::primaryUser() const
|
||||
{
|
||||
QByteArray username;
|
||||
|
||||
memory->lock();
|
||||
auto *inst = static_cast<InstancesInfo*>( memory->data() );
|
||||
username = inst->primaryUser;
|
||||
memory->unlock();
|
||||
|
||||
return QString::fromUtf8( username );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Executed when a connection has been made to the LocalServer
|
||||
*/
|
||||
void SingleApplicationPrivate::slotConnectionEstablished()
|
||||
{
|
||||
QLocalSocket *nextConnSocket = server->nextPendingConnection();
|
||||
connectionMap.insert(nextConnSocket, ConnectionInfo());
|
||||
|
||||
QObject::connect(nextConnSocket, &QLocalSocket::aboutToClose,
|
||||
[nextConnSocket, this](){
|
||||
auto &info = connectionMap[nextConnSocket];
|
||||
Q_EMIT this->slotClientConnectionClosed( nextConnSocket, info.instanceId );
|
||||
}
|
||||
);
|
||||
|
||||
QObject::connect(nextConnSocket, &QLocalSocket::disconnected, nextConnSocket, &QLocalSocket::deleteLater);
|
||||
|
||||
QObject::connect(nextConnSocket, &QLocalSocket::destroyed,
|
||||
[nextConnSocket, this](){
|
||||
connectionMap.remove(nextConnSocket);
|
||||
}
|
||||
);
|
||||
|
||||
QObject::connect(nextConnSocket, &QLocalSocket::readyRead,
|
||||
[nextConnSocket, this](){
|
||||
auto &info = connectionMap[nextConnSocket];
|
||||
switch(info.stage){
|
||||
case StageHeader:
|
||||
readInitMessageHeader(nextConnSocket);
|
||||
break;
|
||||
case StageBody:
|
||||
readInitMessageBody(nextConnSocket);
|
||||
break;
|
||||
case StageConnected:
|
||||
Q_EMIT this->slotDataAvailable( nextConnSocket, info.instanceId );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::readInitMessageHeader( QLocalSocket *sock )
|
||||
{
|
||||
if (!connectionMap.contains( sock )){
|
||||
return;
|
||||
}
|
||||
|
||||
if( sock->bytesAvailable() < ( qint64 )sizeof( quint64 ) ){
|
||||
return;
|
||||
}
|
||||
|
||||
QDataStream headerStream( sock );
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
|
||||
headerStream.setVersion( QDataStream::Qt_5_6 );
|
||||
#endif
|
||||
|
||||
// Read the header to know the message length
|
||||
quint64 msgLen = 0;
|
||||
headerStream >> msgLen;
|
||||
ConnectionInfo &info = connectionMap[sock];
|
||||
info.stage = StageBody;
|
||||
info.msgLen = msgLen;
|
||||
|
||||
if ( sock->bytesAvailable() >= (qint64) msgLen ){
|
||||
readInitMessageBody( sock );
|
||||
}
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::readInitMessageBody( QLocalSocket *sock )
|
||||
{
|
||||
Q_Q(SingleApplication);
|
||||
|
||||
if (!connectionMap.contains( sock )){
|
||||
return;
|
||||
}
|
||||
|
||||
ConnectionInfo &info = connectionMap[sock];
|
||||
if( sock->bytesAvailable() < ( qint64 )info.msgLen ){
|
||||
return;
|
||||
}
|
||||
|
||||
// Read the message body
|
||||
QByteArray msgBytes = sock->read(info.msgLen);
|
||||
QDataStream readStream(msgBytes);
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
|
||||
readStream.setVersion( QDataStream::Qt_5_6 );
|
||||
#endif
|
||||
|
||||
// server name
|
||||
QByteArray latin1Name;
|
||||
readStream >> latin1Name;
|
||||
|
||||
// connection type
|
||||
ConnectionType connectionType = InvalidConnection;
|
||||
quint8 connTypeVal = InvalidConnection;
|
||||
readStream >> connTypeVal;
|
||||
connectionType = static_cast <ConnectionType>( connTypeVal );
|
||||
|
||||
// instance id
|
||||
quint32 instanceId = 0;
|
||||
readStream >> instanceId;
|
||||
|
||||
// checksum
|
||||
quint16 msgChecksum = 0;
|
||||
readStream >> msgChecksum;
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
const quint16 actualChecksum = qChecksum(QByteArray(msgBytes, static_cast<quint32>(msgBytes.length() - sizeof(quint16))));
|
||||
#else
|
||||
const quint16 actualChecksum = qChecksum(msgBytes.constData(), static_cast<quint32>(msgBytes.length() - sizeof(quint16)));
|
||||
#endif
|
||||
|
||||
bool isValid = readStream.status() == QDataStream::Ok &&
|
||||
QLatin1String(latin1Name) == blockServerName &&
|
||||
msgChecksum == actualChecksum;
|
||||
|
||||
if( !isValid ){
|
||||
sock->close();
|
||||
return;
|
||||
}
|
||||
|
||||
info.instanceId = instanceId;
|
||||
info.stage = StageConnected;
|
||||
|
||||
if( connectionType == NewInstance ||
|
||||
( connectionType == SecondaryInstance &&
|
||||
options & SingleApplication::Mode::SecondaryNotification ) )
|
||||
{
|
||||
Q_EMIT q->instanceStarted();
|
||||
}
|
||||
|
||||
if (sock->bytesAvailable() > 0){
|
||||
Q_EMIT this->slotDataAvailable( sock, instanceId );
|
||||
}
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::slotDataAvailable( QLocalSocket *dataSocket, quint32 instanceId )
|
||||
{
|
||||
Q_Q(SingleApplication);
|
||||
Q_EMIT q->receivedMessage( instanceId, dataSocket->readAll() );
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::slotClientConnectionClosed( QLocalSocket *closedSocket, quint32 instanceId )
|
||||
{
|
||||
if( closedSocket->bytesAvailable() > 0 )
|
||||
Q_EMIT slotDataAvailable( closedSocket, instanceId );
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::randomSleep()
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK( 5, 10, 0 )
|
||||
QThread::msleep( QRandomGenerator::global()->bounded( 8u, 18u ));
|
||||
#else
|
||||
qsrand( QDateTime::currentMSecsSinceEpoch() % std::numeric_limits<uint>::max() );
|
||||
QThread::msleep( 8 + static_cast <unsigned long>( static_cast <float>( qrand() ) / RAND_MAX * 10 ));
|
||||
#endif
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::addAppData(const QString &data)
|
||||
{
|
||||
appDataList.push_back(data);
|
||||
}
|
||||
|
||||
QStringList SingleApplicationPrivate::appData() const
|
||||
{
|
||||
return appDataList;
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) Itay Grudev 2015 - 2020
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
//
|
||||
// W A R N I N G !!!
|
||||
// -----------------
|
||||
//
|
||||
// This file is not part of the SingleApplication API. It is used purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or may even be removed.
|
||||
//
|
||||
|
||||
#ifndef SINGLEAPPLICATION_P_H
|
||||
#define SINGLEAPPLICATION_P_H
|
||||
|
||||
#include <QtCore/QSharedMemory>
|
||||
#include <QtNetwork/QLocalServer>
|
||||
#include <QtNetwork/QLocalSocket>
|
||||
#include "singleapplication.h"
|
||||
|
||||
struct InstancesInfo {
|
||||
bool primary;
|
||||
quint32 secondary;
|
||||
qint64 primaryPid;
|
||||
char primaryUser[128];
|
||||
quint16 checksum; // Must be the last field
|
||||
};
|
||||
|
||||
struct ConnectionInfo {
|
||||
qint64 msgLen = 0;
|
||||
quint32 instanceId = 0;
|
||||
quint8 stage = 0;
|
||||
};
|
||||
|
||||
class SingleApplicationPrivate : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum ConnectionType : quint8 {
|
||||
InvalidConnection = 0,
|
||||
NewInstance = 1,
|
||||
SecondaryInstance = 2,
|
||||
Reconnect = 3
|
||||
};
|
||||
enum ConnectionStage : quint8 {
|
||||
StageHeader = 0,
|
||||
StageBody = 1,
|
||||
StageConnected = 2,
|
||||
};
|
||||
Q_DECLARE_PUBLIC(SingleApplication)
|
||||
|
||||
SingleApplicationPrivate( SingleApplication *q_ptr );
|
||||
~SingleApplicationPrivate() override;
|
||||
|
||||
static QString getUsername();
|
||||
void genBlockServerName();
|
||||
void initializeMemoryBlock() const;
|
||||
void startPrimary();
|
||||
void startSecondary();
|
||||
bool connectToPrimary( int msecs, ConnectionType connectionType );
|
||||
quint16 blockChecksum() const;
|
||||
qint64 primaryPid() const;
|
||||
QString primaryUser() const;
|
||||
void readInitMessageHeader(QLocalSocket *socket);
|
||||
void readInitMessageBody(QLocalSocket *socket);
|
||||
static void randomSleep();
|
||||
void addAppData(const QString &data);
|
||||
QStringList appData() const;
|
||||
|
||||
SingleApplication *q_ptr;
|
||||
QSharedMemory *memory;
|
||||
QLocalSocket *socket;
|
||||
QLocalServer *server;
|
||||
quint32 instanceNumber;
|
||||
QString blockServerName;
|
||||
SingleApplication::Options options;
|
||||
QMap<QLocalSocket*, ConnectionInfo> connectionMap;
|
||||
QStringList appDataList;
|
||||
|
||||
public Q_SLOTS:
|
||||
void slotConnectionEstablished();
|
||||
void slotDataAvailable( QLocalSocket*, quint32 );
|
||||
void slotClientConnectionClosed( QLocalSocket*, quint32 );
|
||||
};
|
||||
|
||||
#endif // SINGLEAPPLICATION_P_H
|
||||
2
client/3rd/amneziawg-apple
vendored
@@ -25,16 +25,18 @@ execute_process(
|
||||
add_definitions(-DGIT_COMMIT_HASH="${GIT_COMMIT_HASH}")
|
||||
|
||||
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_ENDPOINT="$ENV{DEV_AGW_ENDPOINT}")
|
||||
add_definitions(-DDEV_S3_ENDPOINT="$ENV{DEV_S3_ENDPOINT}")
|
||||
|
||||
if(IOS)
|
||||
if(IOS OR MACOS_NE)
|
||||
set(PACKAGES ${PACKAGES} Multimedia)
|
||||
endif()
|
||||
|
||||
if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
|
||||
#Macos Network Extension doesn't need Widgets
|
||||
if(WIN32 OR (APPLE AND NOT IOS AND NOT MACOS_NE) OR (LINUX AND NOT ANDROID))
|
||||
set(PACKAGES ${PACKAGES} Widgets)
|
||||
endif()
|
||||
|
||||
@@ -47,18 +49,23 @@ set(LIBS ${LIBS}
|
||||
Qt6::Core5Compat Qt6::Concurrent
|
||||
)
|
||||
|
||||
if(IOS)
|
||||
if(IOS OR MACOS_NE)
|
||||
set(LIBS ${LIBS} Qt6::Multimedia)
|
||||
endif()
|
||||
# message("Client desktop build ", ${MACOS_NE})
|
||||
#Macos Network Extension doesn't need Widgets
|
||||
|
||||
if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
|
||||
if(WIN32 OR (APPLE AND NOT IOS AND NOT MACOS_NE) OR (LINUX AND NOT ANDROID))
|
||||
message("Run this block when MACOS_NE is not defined or set to FALSE")
|
||||
set(LIBS ${LIBS} Qt6::Widgets)
|
||||
endif()
|
||||
|
||||
qt_standard_project_setup()
|
||||
qt_add_executable(${PROJECT} MANUAL_FINALIZATION)
|
||||
|
||||
if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
|
||||
# TODO error in there
|
||||
if(WIN32 OR (APPLE AND NOT IOS AND NOT MACOS_NE) OR (LINUX AND NOT ANDROID))
|
||||
message("Run this block when MACOS_NE is not defined or set to FALSE")
|
||||
qt_add_repc_replicas(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/../ipc/ipc_interface.rep)
|
||||
qt_add_repc_replicas(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/../ipc/ipc_process_interface.rep)
|
||||
qt_add_repc_replicas(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/../ipc/ipc_process_tun2socks.rep)
|
||||
@@ -96,10 +103,18 @@ qt6_add_resources(QRC ${I18NQRC} ${CMAKE_CURRENT_BINARY_DIR}/translations.qrc)
|
||||
# -- i18n end
|
||||
|
||||
if(IOS)
|
||||
message("Building for iOS")
|
||||
execute_process(COMMAND bash ${CMAKE_CURRENT_LIST_DIR}/ios/scripts/openvpn.sh args
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
||||
endif()
|
||||
|
||||
# Build openvpn adapter for MacOS Network Extension
|
||||
if(MACOS_NE)
|
||||
message("Building for MacOS Network Extension")
|
||||
execute_process(COMMAND bash ${CMAKE_CURRENT_LIST_DIR}/macos/scripts/openvpn.sh args
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
||||
endif()
|
||||
|
||||
set(IS_CI ${CI})
|
||||
if(IS_CI)
|
||||
message("Detected CI env")
|
||||
@@ -160,12 +175,24 @@ include_directories(mozilla)
|
||||
include_directories(mozilla/shared)
|
||||
include_directories(mozilla/models)
|
||||
|
||||
if(NOT IOS)
|
||||
if(MACOS_NE)
|
||||
message("MACOS_NE is ON")
|
||||
add_definitions(-DQ_OS_IOS)
|
||||
add_definitions(-DMACOS_NE)
|
||||
message("Add macros for MacOS Network Extension")
|
||||
else()
|
||||
message("MACOS_NE is OFF")
|
||||
endif()
|
||||
|
||||
|
||||
if(NOT IOS AND NOT MACOS_NE)
|
||||
message(" Add header for non-IOS and non-MACOS_NE")
|
||||
set(HEADERS ${HEADERS}
|
||||
${CMAKE_CURRENT_LIST_DIR}/platforms/ios/QRCodeReaderBase.h
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
if(NOT ANDROID)
|
||||
set(HEADERS ${HEADERS}
|
||||
${CMAKE_CURRENT_LIST_DIR}/ui/notificationhandler.h
|
||||
@@ -210,7 +237,7 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
target_compile_definitions(${PROJECT} PRIVATE "MZ_DEBUG")
|
||||
endif()
|
||||
|
||||
if(NOT IOS)
|
||||
if(NOT IOS AND NOT MACOS_NE)
|
||||
set(SOURCES ${SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/platforms/ios/QRCodeReaderBase.cpp
|
||||
)
|
||||
@@ -311,6 +338,7 @@ if(APPLE)
|
||||
set(CMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM ${BUILD_VPN_DEVELOPMENT_TEAM})
|
||||
set(CMAKE_XCODE_ATTRIBUTE_GROUP_ID_IOS ${BUILD_IOS_GROUP_IDENTIFIER})
|
||||
|
||||
set(MACOSX_DEPLOYMENT_TARGET "12.0")
|
||||
endif()
|
||||
|
||||
if(LINUX AND NOT ANDROID)
|
||||
@@ -318,10 +346,9 @@ if(LINUX AND NOT ANDROID)
|
||||
link_directories(${CMAKE_CURRENT_LIST_DIR}/platforms/linux)
|
||||
endif()
|
||||
|
||||
if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
|
||||
message("Client desktop build")
|
||||
# Macos Network Extension doesn't need
|
||||
if(WIN32 OR (APPLE AND NOT IOS AND NOT MACOS_NE) OR (LINUX AND NOT ANDROID))
|
||||
add_compile_definitions(AMNEZIA_DESKTOP)
|
||||
|
||||
set(HEADERS ${HEADERS}
|
||||
${CMAKE_CURRENT_LIST_DIR}/core/ipcclient.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/core/privileged_process.h
|
||||
@@ -354,9 +381,12 @@ endif()
|
||||
if(IOS)
|
||||
include(cmake/ios.cmake)
|
||||
include(cmake/ios-arch-fixup.cmake)
|
||||
elseif(APPLE AND NOT IOS)
|
||||
include(cmake/osxtools.cmake)
|
||||
elseif(APPLE AND NOT IOS AND NOT DEFINED MACOS_NE)
|
||||
# include(cmake/osxtools.cmake)
|
||||
include(cmake/macos.cmake)
|
||||
elseif(APPLE AND NOT IOS AND MACOS_NE)
|
||||
include(cmake/osxtools.cmake)
|
||||
include(cmake/macos_ne.cmake)
|
||||
endif()
|
||||
|
||||
target_link_libraries(${PROJECT} PRIVATE ${LIBS})
|
||||
@@ -375,7 +405,7 @@ elseif(APPLE AND NOT IOS)
|
||||
set(DEPLOY_PLATFORM_PATH "macos")
|
||||
endif()
|
||||
|
||||
if(NOT IOS AND NOT ANDROID)
|
||||
if(NOT IOS AND NOT ANDROID AND NOT MACOS_NE)
|
||||
add_custom_command(
|
||||
TARGET ${PROJECT} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E $<IF:$<CONFIG:Debug>,copy_directory,true>
|
||||
@@ -394,4 +424,36 @@ if(NOT IOS AND NOT ANDROID)
|
||||
endif()
|
||||
|
||||
target_sources(${PROJECT} PRIVATE ${SOURCES} ${HEADERS} ${RESOURCES} ${QRC} ${I18NQRC})
|
||||
if(MACOS_NE)
|
||||
message("Copy MacOS Network Extension files")
|
||||
|
||||
add_custom_command(TARGET ${PROJECT} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory
|
||||
$<TARGET_BUNDLE_DIR:AmneziaVPN>/Contents/Frameworks
|
||||
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "Copying OpenVPNAdapter.framework..."
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
${CMAKE_SOURCE_DIR}/client/3rd/OpenVPNAdapter/build/Release-macos/OpenVPNAdapter.framework/Versions/A
|
||||
$<TARGET_BUNDLE_DIR:AmneziaVPN>/Contents/Frameworks/OpenVPNAdapter.framework/Versions/A
|
||||
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "OpenVPNAdapter.framework copied successfully."
|
||||
)
|
||||
|
||||
# MacOS specific application deployment
|
||||
add_custom_command(TARGET ${PROJECT} POST_BUILD
|
||||
COMMAND ${QT_BIN_DIR_DETECTED}/macdeployqt $<TARGET_BUNDLE_DIR:AmneziaVPN> -appstore-compliant -qmldir=${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
# MacOS specific code signing for Release
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
SET(SIGN_CMD codesign --deep --force --sign 'Apple Distribution: Privacy Technologies OU \(X7UJ388FXK\)' --timestamp --options runtime $<TARGET_BUNDLE_DIR:AmneziaVPN>)
|
||||
message("Manual signing bundle...")
|
||||
message(${SIGN_CMD})
|
||||
|
||||
add_custom_command(TARGET ${PROJECT} POST_BUILD
|
||||
COMMAND ${SIGN_CMD}
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
qt_finalize_target(${PROJECT})
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include <QTextDocument>
|
||||
#include <QTimer>
|
||||
#include <QTranslator>
|
||||
#include <QLocalSocket>
|
||||
#include <QLocalServer>
|
||||
|
||||
#include "logger.h"
|
||||
#include "ui/models/installedAppsModel.h"
|
||||
@@ -28,13 +30,7 @@
|
||||
#include <AmneziaVPN-Swift.h>
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||
AmneziaApplication::AmneziaApplication(int &argc, char *argv[]) : AMNEZIA_BASE_CLASS(argc, argv)
|
||||
#else
|
||||
AmneziaApplication::AmneziaApplication(int &argc, char *argv[], bool allowSecondary, SingleApplication::Options options, int timeout,
|
||||
const QString &userData)
|
||||
: SingleApplication(argc, argv, allowSecondary, options, timeout, userData)
|
||||
#endif
|
||||
{
|
||||
setQuitOnLastWindowClosed(false);
|
||||
|
||||
@@ -115,10 +111,11 @@ void AmneziaApplication::init()
|
||||
qFatal("Android controller initialization failed");
|
||||
}
|
||||
|
||||
connect(AndroidController::instance(), &AndroidController::importConfigFromOutside, [this](QString data) {
|
||||
m_pageController->goToPageHome();
|
||||
connect(AndroidController::instance(), &AndroidController::importConfigFromOutside, this, [this](QString data) {
|
||||
emit m_pageController->goToPageHome();
|
||||
m_importController->extractConfigFromData(data);
|
||||
m_pageController->goToPageViewConfig();
|
||||
data.clear();
|
||||
emit m_pageController->goToPageViewConfig();
|
||||
});
|
||||
|
||||
m_engine->addImageProvider(QLatin1String("installedAppImage"), new InstalledAppsImageProvider);
|
||||
@@ -126,16 +123,16 @@ void AmneziaApplication::init()
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
IosController::Instance()->initialize();
|
||||
connect(IosController::Instance(), &IosController::importConfigFromOutside, [this](QString data) {
|
||||
m_pageController->goToPageHome();
|
||||
connect(IosController::Instance(), &IosController::importConfigFromOutside, this, [this](QString data) {
|
||||
emit m_pageController->goToPageHome();
|
||||
m_importController->extractConfigFromData(data);
|
||||
m_pageController->goToPageViewConfig();
|
||||
emit m_pageController->goToPageViewConfig();
|
||||
});
|
||||
|
||||
connect(IosController::Instance(), &IosController::importBackupFromOutside, [this](QString filePath) {
|
||||
m_pageController->goToPageHome();
|
||||
connect(IosController::Instance(), &IosController::importBackupFromOutside, this, [this](QString filePath) {
|
||||
emit m_pageController->goToPageHome();
|
||||
m_pageController->goToPageSettingsBackup();
|
||||
m_settingsController->importBackupFromOutside(filePath);
|
||||
emit m_settingsController->importBackupFromOutside(filePath);
|
||||
});
|
||||
|
||||
QTimer::singleShot(0, this, [this]() { AmneziaVPN::toggleScreenshots(m_settings->isScreenshotsEnabled()); });
|
||||
@@ -180,16 +177,6 @@ void AmneziaApplication::init()
|
||||
m_pageController->showOnStartup();
|
||||
#endif
|
||||
|
||||
// TODO - fix
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||
if (isPrimary()) {
|
||||
QObject::connect(this, &SingleApplication::instanceStarted, m_pageController.get(), [this]() {
|
||||
qDebug() << "Secondary instance started, showing this window instead";
|
||||
emit m_pageController->raiseMainWindow();
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
// Android TextArea clipboard workaround
|
||||
// Text from TextArea always has "text/html" mime-type:
|
||||
// /qt/6.6.1/Src/qtdeclarative/src/quick/items/qquicktextcontrol.cpp:1865
|
||||
@@ -294,6 +281,24 @@ bool AmneziaApplication::parseCommands()
|
||||
return true;
|
||||
}
|
||||
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||
void AmneziaApplication::startLocalServer() {
|
||||
const QString serverName("AmneziaVPNInstance");
|
||||
QLocalServer::removeServer(serverName);
|
||||
|
||||
QLocalServer* server = new QLocalServer(this);
|
||||
server->listen(serverName);
|
||||
|
||||
QObject::connect(server, &QLocalServer::newConnection, this, [server, this]() {
|
||||
if (server) {
|
||||
QLocalSocket* clientConnection = server->nextPendingConnection();
|
||||
clientConnection->deleteLater();
|
||||
}
|
||||
emit m_pageController->raiseMainWindow();
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
QQmlApplicationEngine *AmneziaApplication::qmlEngine() const
|
||||
{
|
||||
return m_engine;
|
||||
|
||||
@@ -53,22 +53,14 @@
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||
#define AMNEZIA_BASE_CLASS QGuiApplication
|
||||
#else
|
||||
#define AMNEZIA_BASE_CLASS SingleApplication
|
||||
#define QAPPLICATION_CLASS QApplication
|
||||
#include "singleapplication.h"
|
||||
#define AMNEZIA_BASE_CLASS QApplication
|
||||
#endif
|
||||
|
||||
class AmneziaApplication : public AMNEZIA_BASE_CLASS
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||
AmneziaApplication(int &argc, char *argv[]);
|
||||
#else
|
||||
AmneziaApplication(int &argc, char *argv[], bool allowSecondary = false,
|
||||
SingleApplication::Options options = SingleApplication::User, int timeout = 1000,
|
||||
const QString &userData = {});
|
||||
#endif
|
||||
virtual ~AmneziaApplication();
|
||||
|
||||
void init();
|
||||
@@ -78,6 +70,10 @@ public:
|
||||
void updateTranslator(const QLocale &locale);
|
||||
bool parseCommands();
|
||||
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||
void startLocalServer();
|
||||
#endif
|
||||
|
||||
QQmlApplicationEngine *qmlEngine() const;
|
||||
QNetworkAccessManager *manager() { return m_nam; }
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ android.library.defaults.buildfeatures.androidresources=false
|
||||
# For development copy and set local values for these parameters in local.properties
|
||||
#androidCompileSdkVersion=android-34
|
||||
#androidBuildToolsVersion=34.0.0
|
||||
#qtMinSdkVersion=24
|
||||
#qtMinSdkVersion=26
|
||||
#qtTargetSdkVersion=34
|
||||
#androidNdkVersion=26.1.10909125
|
||||
#qtTargetAbiList=x86_64
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.amnezia.vpn.protocol
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.net.IpPrefix
|
||||
import android.net.VpnService
|
||||
@@ -8,9 +7,6 @@ import android.net.VpnService.Builder
|
||||
import android.os.Build
|
||||
import android.system.OsConstants
|
||||
import androidx.annotation.RequiresApi
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.util.zip.ZipFile
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import org.amnezia.vpn.util.Log
|
||||
import org.amnezia.vpn.util.net.InetNetwork
|
||||
|
||||
@@ -21,6 +21,7 @@ import android.os.Looper
|
||||
import android.os.Message
|
||||
import android.os.Messenger
|
||||
import android.provider.Settings
|
||||
import android.view.MotionEvent
|
||||
import android.view.WindowManager.LayoutParams
|
||||
import android.webkit.MimeTypeMap
|
||||
import android.widget.Toast
|
||||
@@ -158,7 +159,7 @@ class AmneziaActivity : QtActivity() {
|
||||
*/
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
Log.d(TAG, "Create Amnezia activity: $intent")
|
||||
Log.d(TAG, "Create Amnezia activity")
|
||||
loadLibs()
|
||||
window.apply {
|
||||
addFlags(LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
|
||||
@@ -200,7 +201,7 @@ class AmneziaActivity : QtActivity() {
|
||||
NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED
|
||||
)
|
||||
) {
|
||||
Log.d(
|
||||
Log.v(
|
||||
TAG, "Notification state changed: ${it?.action}, blocked = " +
|
||||
"${it?.getBooleanExtra(NotificationManager.EXTRA_BLOCKED_STATE, false)}"
|
||||
)
|
||||
@@ -214,7 +215,7 @@ class AmneziaActivity : QtActivity() {
|
||||
|
||||
override fun onNewIntent(intent: Intent?) {
|
||||
super.onNewIntent(intent)
|
||||
Log.d(TAG, "onNewIntent: $intent")
|
||||
Log.v(TAG, "onNewIntent: $intent")
|
||||
intent?.let(::processIntent)
|
||||
}
|
||||
|
||||
@@ -403,7 +404,7 @@ class AmneziaActivity : QtActivity() {
|
||||
@MainThread
|
||||
private fun startVpn(vpnConfig: String) {
|
||||
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 (proto.serviceClass == vpnProto?.serviceClass) {
|
||||
vpnProto = proto
|
||||
@@ -516,7 +517,7 @@ class AmneziaActivity : QtActivity() {
|
||||
startActivityForResult(it, CREATE_FILE_ACTION_CODE, ActivityResultHandler(
|
||||
onSuccess = {
|
||||
it?.data?.let { uri ->
|
||||
Log.d(TAG, "Save file to $uri")
|
||||
Log.v(TAG, "Save file to $uri")
|
||||
try {
|
||||
contentResolver.openOutputStream(uri)?.use { os ->
|
||||
os.bufferedWriter().use { it.write(data) }
|
||||
@@ -565,7 +566,7 @@ class AmneziaActivity : QtActivity() {
|
||||
startActivityForResult(it, OPEN_FILE_ACTION_CODE, ActivityResultHandler(
|
||||
onAny = {
|
||||
val uri = it?.data?.toString() ?: ""
|
||||
Log.d(TAG, "Open file: $uri")
|
||||
Log.v(TAG, "Open file: $uri")
|
||||
mainScope.launch {
|
||||
qtInitialized.await()
|
||||
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
|
||||
*/
|
||||
|
||||
@@ -22,6 +22,7 @@ import androidx.annotation.MainThread
|
||||
import androidx.core.app.ServiceCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.getSystemService
|
||||
import java.net.UnknownHostException
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import kotlin.LazyThreadSafetyMode.NONE
|
||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||
@@ -127,6 +128,8 @@ open class AmneziaVpnService : VpnService() {
|
||||
|
||||
is LoadLibraryException -> onError("${e.message}. Caused: ${e.cause?.message}")
|
||||
|
||||
is UnknownHostException -> onError("Unknown host")
|
||||
|
||||
else -> throw e
|
||||
}
|
||||
}
|
||||
@@ -297,7 +300,7 @@ open class AmneziaVpnService : VpnService() {
|
||||
arrayOf(ACTION_CONNECT, ACTION_DISCONNECT), ContextCompat.RECEIVER_NOT_EXPORTED
|
||||
) {
|
||||
it?.action?.let { action ->
|
||||
Log.d(TAG, "Broadcast request received: $action")
|
||||
Log.v(TAG, "Broadcast request received: $action")
|
||||
when (action) {
|
||||
ACTION_CONNECT -> connect()
|
||||
ACTION_DISCONNECT -> disconnect()
|
||||
@@ -314,7 +317,7 @@ open class AmneziaVpnService : VpnService() {
|
||||
)
|
||||
) {
|
||||
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) {
|
||||
enableNotification()
|
||||
} else {
|
||||
@@ -447,7 +450,7 @@ open class AmneziaVpnService : VpnService() {
|
||||
serviceNotification.isNotificationEnabled() &&
|
||||
getSystemService<PowerManager>()?.isInteractive != false
|
||||
) {
|
||||
Log.d(TAG, "Launch traffic stats update")
|
||||
Log.v(TAG, "Launch traffic stats update")
|
||||
trafficStats.reset()
|
||||
startTrafficStatsUpdateJob()
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ class AuthActivity : FragmentActivity() {
|
||||
object : BiometricPrompt.AuthenticationCallback() {
|
||||
override fun onAuthenticationSucceeded(result: AuthenticationResult) {
|
||||
super.onAuthenticationSucceeded(result)
|
||||
Log.d(TAG, "Authentication succeeded")
|
||||
Log.v(TAG, "Authentication succeeded")
|
||||
QtAndroidController.onAuthResult(true)
|
||||
finish()
|
||||
}
|
||||
|
||||
@@ -29,20 +29,20 @@ class ImportConfigActivity : ComponentActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
Log.d(TAG, "Create Import Config Activity: $intent")
|
||||
Log.v(TAG, "Create Import Config Activity: $intent")
|
||||
intent?.let(::readConfig)
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent) {
|
||||
super.onNewIntent(intent)
|
||||
Log.d(TAG, "onNewIntent: $intent")
|
||||
Log.v(TAG, "onNewIntent: $intent")
|
||||
intent.let(::readConfig)
|
||||
}
|
||||
|
||||
private fun readConfig(intent: Intent) {
|
||||
when (intent.action) {
|
||||
ACTION_SEND -> {
|
||||
Log.d(TAG, "Process SEND action, type: ${intent.type}")
|
||||
Log.v(TAG, "Process SEND action, type: ${intent.type}")
|
||||
when (intent.type) {
|
||||
"application/octet-stream" -> {
|
||||
intent.getUriCompat()?.let { uri ->
|
||||
@@ -60,7 +60,7 @@ class ImportConfigActivity : ComponentActivity() {
|
||||
}
|
||||
|
||||
ACTION_VIEW -> {
|
||||
Log.d(TAG, "Process VIEW action, scheme: ${intent.scheme}")
|
||||
Log.v(TAG, "Process VIEW action, scheme: ${intent.scheme}")
|
||||
when (intent.scheme) {
|
||||
"file", "content" -> {
|
||||
intent.data?.let { uri ->
|
||||
|
||||
@@ -62,7 +62,7 @@ class ServiceNotification(private val context: Context) {
|
||||
fun buildNotification(serverName: String?, protocol: String?, state: ProtocolState): Notification {
|
||||
val speedString = if (state == CONNECTED) zeroSpeed else null
|
||||
|
||||
Log.d(TAG, "Build notification: $serverName, $state")
|
||||
Log.v(TAG, "Build notification: $serverName, $state")
|
||||
|
||||
return notificationBuilder
|
||||
.setSmallIcon(R.drawable.ic_amnezia_round)
|
||||
@@ -88,17 +88,15 @@ class ServiceNotification(private val context: Context) {
|
||||
fun isNotificationEnabled(): Boolean {
|
||||
if (!context.isNotificationPermissionGranted()) return false
|
||||
if (!notificationManager.areNotificationsEnabled()) return false
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
return notificationManager.getNotificationChannel(NOTIFICATION_CHANNEL_ID)
|
||||
?.let { it.importance != NotificationManager.IMPORTANCE_NONE } ?: true
|
||||
}
|
||||
return true
|
||||
return notificationManager.getNotificationChannel(NOTIFICATION_CHANNEL_ID)?.let {
|
||||
it.importance != NotificationManager.IMPORTANCE_NONE
|
||||
} ?: true
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
fun updateNotification(serverName: String?, protocol: String?, state: ProtocolState) {
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ object LibraryLoader {
|
||||
System.loadLibrary(libraryName)
|
||||
return
|
||||
} 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
|
||||
try {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package org.amnezia.vpn.util
|
||||
|
||||
import android.content.Context
|
||||
import android.icu.text.DateFormat
|
||||
import android.icu.text.SimpleDateFormat
|
||||
import android.os.Build
|
||||
import android.os.Process
|
||||
import java.io.File
|
||||
@@ -12,8 +10,6 @@ import java.nio.channels.FileChannel
|
||||
import java.nio.channels.FileLock
|
||||
import java.time.LocalDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
import org.amnezia.vpn.util.Log.Priority.D
|
||||
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 |
|
||||
*/
|
||||
object Log {
|
||||
private val dateTimeFormat: Any =
|
||||
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 val dateTimeFormat: DateTimeFormatter = DateTimeFormatter.ofPattern(DATE_TIME_PATTERN)
|
||||
|
||||
private lateinit var logDir: File
|
||||
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 {
|
||||
val date = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
LocalDateTime.now().format(dateTimeFormat as DateTimeFormatter)
|
||||
} else {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
(dateTimeFormat as ThreadLocal<DateFormat>).get()?.format(Date())
|
||||
}
|
||||
val date = LocalDateTime.now().format(dateTimeFormat)
|
||||
return "$date ${Process.myPid()} ${Process.myTid()} $priority [${Thread.currentThread().name}] " +
|
||||
"$tag: $msg\n"
|
||||
}
|
||||
|
||||
@@ -42,18 +42,12 @@ class NetworkState(
|
||||
private val networkCallback: NetworkCallback by lazy(NONE) {
|
||||
object : NetworkCallback() {
|
||||
override fun onAvailable(network: Network) {
|
||||
Log.d(TAG, "onAvailable: $network")
|
||||
Log.v(TAG, "onAvailable: $network")
|
||||
}
|
||||
|
||||
override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {
|
||||
Log.d(TAG, "onCapabilitiesChanged: $network, $networkCapabilities")
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
checkNetworkState(network, networkCapabilities)
|
||||
} else {
|
||||
handler.post {
|
||||
checkNetworkState(network, networkCapabilities)
|
||||
}
|
||||
}
|
||||
Log.v(TAG, "onCapabilitiesChanged: $network, $networkCapabilities")
|
||||
checkNetworkState(network, networkCapabilities)
|
||||
}
|
||||
|
||||
private fun checkNetworkState(network: Network, networkCapabilities: NetworkCapabilities) {
|
||||
@@ -73,11 +67,11 @@ class NetworkState(
|
||||
}
|
||||
|
||||
override fun onBlockedStatusChanged(network: Network, blocked: Boolean) {
|
||||
Log.d(TAG, "onBlockedStatusChanged: $network, $blocked")
|
||||
Log.v(TAG, "onBlockedStatusChanged: $network, $blocked")
|
||||
}
|
||||
|
||||
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")
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
connectivityManager.registerBestMatchingNetworkCallback(networkRequest, networkCallback, handler)
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
} else {
|
||||
val numberAttempts = 300
|
||||
var attemptCount = 0
|
||||
while(true) {
|
||||
@@ -108,8 +102,6 @@ class NetworkState(
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
connectivityManager.requestNetwork(networkRequest, networkCallback)
|
||||
}
|
||||
isListenerBound = true
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ open class Wireguard : Protocol() {
|
||||
try {
|
||||
delay(1000)
|
||||
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,
|
||||
// to avoid infinite connection
|
||||
if (!log.contains("Attaching to interface")) {
|
||||
|
||||
@@ -130,8 +130,8 @@ class Xray : Protocol() {
|
||||
LibXray.initXray(assetsPath)
|
||||
val geoDir = File(assetsPath, "geo").absolutePath
|
||||
val configPath = File(context.cacheDir, "config.json")
|
||||
Log.d(TAG, "xray.location.asset: $geoDir")
|
||||
Log.d(TAG, "config: $configPath")
|
||||
Log.v(TAG, "xray.location.asset: $geoDir")
|
||||
Log.v(TAG, "config: $configPath")
|
||||
try {
|
||||
configPath.writeText(configJson)
|
||||
} catch (e: IOException) {
|
||||
|
||||
@@ -2,10 +2,6 @@ set(CLIENT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/..)
|
||||
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/Modules;${CMAKE_MODULE_PATH}")
|
||||
|
||||
if(NOT IOS AND NOT ANDROID)
|
||||
include(${CLIENT_ROOT_DIR}/3rd/SingleApplication/singleapplication.cmake)
|
||||
endif()
|
||||
|
||||
add_subdirectory(${CLIENT_ROOT_DIR}/3rd/SortFilterProxyModel)
|
||||
set(LIBS ${LIBS} SortFilterProxyModel)
|
||||
include(${CLIENT_ROOT_DIR}/cmake/QSimpleCrypto.cmake)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
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
|
||||
"The minimum API level supported by the application or library" FORCE)
|
||||
|
||||
|
||||
140
client/cmake/macos_ne.cmake
Normal file
@@ -0,0 +1,140 @@
|
||||
message("Client ==> MacOS NE build")
|
||||
|
||||
set_target_properties(${PROJECT} PROPERTIES MACOSX_BUNDLE TRUE)
|
||||
set(CMAKE_OSX_ARCHITECTURES "x86_64")
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.15)
|
||||
set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf-with-dsym")
|
||||
set(APPLE_PROJECT_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
|
||||
|
||||
|
||||
enable_language(OBJC)
|
||||
enable_language(Swift)
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS ShaderTools)
|
||||
set(LIBS ${LIBS} Qt6::ShaderTools)
|
||||
|
||||
find_library(FW_AUTHENTICATIONSERVICES AuthenticationServices)
|
||||
find_library(FW_AVFOUNDATION AVFoundation)
|
||||
find_library(FW_FOUNDATION Foundation)
|
||||
find_library(FW_STOREKIT StoreKit)
|
||||
find_library(FW_USERNOTIFICATIONS UserNotifications)
|
||||
find_library(FW_NETWORKEXTENSION NetworkExtension)
|
||||
|
||||
set(LIBS ${LIBS}
|
||||
${FW_AUTHENTICATIONSERVICES}
|
||||
${FW_AVFOUNDATION}
|
||||
${FW_FOUNDATION}
|
||||
${FW_STOREKIT}
|
||||
${FW_USERNOTIFICATIONS}
|
||||
${FW_NETWORKEXTENSION}
|
||||
)
|
||||
|
||||
|
||||
set(HEADERS ${HEADERS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/ios_controller.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/ios_controller_wrapper.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/iosnotificationhandler.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/QtAppDelegate.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/QtAppDelegate-C-Interface.h
|
||||
)
|
||||
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/ios_controller.h PROPERTIES OBJECTIVE_CPP_HEADER TRUE)
|
||||
|
||||
|
||||
set(SOURCES ${SOURCES}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/ios_controller.mm
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/ios_controller_wrapper.mm
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/iosnotificationhandler.mm
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/iosglue.mm
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/QRCodeReaderBase.mm
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/QtAppDelegate.mm
|
||||
)
|
||||
|
||||
target_include_directories(${PROJECT} PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS})
|
||||
|
||||
|
||||
set_target_properties(${PROJECT} PROPERTIES
|
||||
XCODE_LINK_BUILD_PHASE_MODE KNOWN_LOCATION
|
||||
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/macos/app/Info.plist.in
|
||||
MACOSX_BUNDLE_ICON_FILE "AppIcon"
|
||||
MACOSX_BUNDLE_INFO_STRING "AmneziaVPN"
|
||||
MACOSX_BUNDLE_BUNDLE_NAME "AmneziaVPN"
|
||||
MACOSX_BUNDLE_BUNDLE_VERSION "${CMAKE_PROJECT_VERSION_TWEAK}"
|
||||
MACOSX_BUNDLE_LONG_VERSION_STRING "${APPLE_PROJECT_VERSION}-${CMAKE_PROJECT_VERSION_TWEAK}"
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING "${APPLE_PROJECT_VERSION}"
|
||||
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "${BUILD_IOS_APP_IDENTIFIER}"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/ios/app/main.entitlements"
|
||||
XCODE_ATTRIBUTE_MARKETING_VERSION "${APPLE_PROJECT_VERSION}"
|
||||
XCODE_ATTRIBUTE_CURRENT_PROJECT_VERSION "${CMAKE_PROJECT_VERSION_TWEAK}"
|
||||
XCODE_ATTRIBUTE_PRODUCT_NAME "AmneziaVPN"
|
||||
XCODE_ATTRIBUTE_BUNDLE_INFO_STRING "AmneziaVPN"
|
||||
XCODE_GENERATE_SCHEME TRUE
|
||||
XCODE_ATTRIBUTE_ENABLE_BITCODE "NO"
|
||||
XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME "AppIcon"
|
||||
XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2"
|
||||
XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY "NO"
|
||||
XCODE_EMBED_FRAMEWORKS_REMOVE_HEADERS_ON_COPY "YES"
|
||||
|
||||
XCODE_LINK_BUILD_PHASE_MODE KNOWN_LOCATION
|
||||
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../Frameworks"
|
||||
XCODE_EMBED_APP_EXTENSIONS networkextension
|
||||
|
||||
# XCODE_ATTRIBUTE_CODE_SIGN_STYLE Automatic
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_STYLE Manual
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Distribution: Privacy Technologies OU (X7UJ388FXK)"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY[variant=Debug] "Apple Development"
|
||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER "Mac AppStore AmneziaVPN"
|
||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER[variant=Debug] "org.amnezia.AmneziaVPNManual"
|
||||
)
|
||||
set_target_properties(${PROJECT} PROPERTIES
|
||||
XCODE_ATTRIBUTE_SWIFT_VERSION "5.0"
|
||||
XCODE_ATTRIBUTE_CLANG_ENABLE_MODULES "YES"
|
||||
XCODE_ATTRIBUTE_SWIFT_PRECOMPILE_BRIDGING_HEADER "NO"
|
||||
XCODE_ATTRIBUTE_SWIFT_OBJC_INTERFACE_HEADER_NAME "AmneziaVPN-Swift.h"
|
||||
XCODE_ATTRIBUTE_SWIFT_OBJC_INTEROP_MODE "objcxx"
|
||||
)
|
||||
set_target_properties(${PROJECT} PROPERTIES
|
||||
XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "X7UJ388FXK"
|
||||
)
|
||||
target_include_directories(${PROJECT} PRIVATE ${CMAKE_CURRENT_LIST_DIR})
|
||||
target_compile_options(${PROJECT} PRIVATE
|
||||
-DGROUP_ID=\"${BUILD_IOS_GROUP_IDENTIFIER}\"
|
||||
-DVPN_NE_BUNDLEID=\"${BUILD_IOS_APP_IDENTIFIER}.network-extension\"
|
||||
)
|
||||
|
||||
set(WG_APPLE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/3rd/amneziawg-apple/Sources)
|
||||
|
||||
target_sources(${PROJECT} PRIVATE
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKitC/x25519.c
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/LogController.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/Log.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/LogRecord.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/ScreenProtection.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/VPNCController.swift
|
||||
)
|
||||
|
||||
target_sources(${PROJECT} PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/macos/app/Images.xcassets
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/PrivacyInfo.xcprivacy
|
||||
)
|
||||
|
||||
set_property(TARGET ${PROJECT} APPEND PROPERTY RESOURCE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/macos/app/Images.xcassets
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/PrivacyInfo.xcprivacy
|
||||
)
|
||||
|
||||
add_subdirectory(macos/networkextension)
|
||||
add_dependencies(${PROJECT} networkextension)
|
||||
|
||||
get_target_property(QtCore_location Qt6::Core LOCATION)
|
||||
message("QtCore_location")
|
||||
message(${QtCore_location})
|
||||
|
||||
get_filename_component(QT_BIN_DIR_DETECTED "${QtCore_location}/../../../../../bin" ABSOLUTE)
|
||||
|
||||
set_property(TARGET ${PROJECT} PROPERTY XCODE_EMBED_FRAMEWORKS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/3rd/OpenVPNAdapter/build/Release-macos/OpenVPNAdapter.framework"
|
||||
)
|
||||
|
||||
set(CMAKE_XCODE_ATTRIBUTE_FRAMEWORK_SEARCH_PATHS ${CMAKE_CURRENT_SOURCE_DIR}/3rd/OpenVPNAdapter/build/Release-macos)
|
||||
target_link_libraries("networkextension" PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/3rd/OpenVPNAdapter/build/Release-macos/OpenVPNAdapter.framework")
|
||||
|
||||
@@ -76,7 +76,7 @@ function(osx_bundle_assetcatalog TARGET)
|
||||
)
|
||||
|
||||
## Patch the asset catalog into the target bundle.
|
||||
if(NOT IOS)
|
||||
if(NOT IOS AND NOT MACOS_NE)
|
||||
set(XCASSETS_RESOURCE_DIR "Resources")
|
||||
endif()
|
||||
add_custom_command(TARGET ${TARGET} POST_BUILD
|
||||
@@ -141,6 +141,7 @@ function(osx_codesign_target TARGET)
|
||||
endif()
|
||||
|
||||
foreach(FILE ${CODESIGN_FILES})
|
||||
message(STATUS "Signing ${TARGET}: ${FILE}")
|
||||
add_custom_command(TARGET ${TARGET} POST_BUILD VERBATIM
|
||||
COMMAND ${COMMENT_ECHO_COMMAND} "Signing ${TARGET}: ${FILE}"
|
||||
COMMAND ${CODESIGN_BIN} ${CODESIGN_ARGS} ${FILE}
|
||||
|
||||
@@ -102,7 +102,9 @@ QProcessEnvironment SshConfigurator::prepareEnv()
|
||||
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\cygwin;");
|
||||
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\openvpn;");
|
||||
#elif defined(Q_OS_MACX)
|
||||
#if !defined(MACOS_NE)
|
||||
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "/Contents/MacOS");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
env.insert("PATH", pathEnvVar);
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#include "apiController.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <random>
|
||||
|
||||
#include <QEventLoop>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
@@ -11,6 +14,7 @@
|
||||
#include "amnezia_application.h"
|
||||
#include "configurators/wireguard_configurator.h"
|
||||
#include "core/enums/apiEnums.h"
|
||||
#include "utilities.h"
|
||||
#include "version.h"
|
||||
|
||||
namespace
|
||||
@@ -33,6 +37,7 @@ namespace
|
||||
constexpr char userCountryCode[] = "user_country_code";
|
||||
constexpr char serverCountryCode[] = "server_country_code";
|
||||
constexpr char serviceType[] = "service_type";
|
||||
constexpr char serviceInfo[] = "service_info";
|
||||
|
||||
constexpr char aesKey[] = "aes_key";
|
||||
constexpr char aesIv[] = "aes_iv";
|
||||
@@ -40,9 +45,10 @@ namespace
|
||||
|
||||
constexpr char apiPayload[] = "api_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)
|
||||
{
|
||||
@@ -63,6 +69,28 @@ namespace
|
||||
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)
|
||||
@@ -94,8 +122,8 @@ void ApiController::fillServerConfig(const QString &protocol, const ApiControlle
|
||||
configStr.replace("$OPENVPN_PRIV_KEY", apiPayloadData.certRequest.privKey);
|
||||
} else if (protocol == configKey::awg) {
|
||||
configStr.replace("$WIREGUARD_CLIENT_PRIVATE_KEY", apiPayloadData.wireGuardClientPrivKey);
|
||||
auto serverConfig = QJsonDocument::fromJson(configStr.toUtf8()).object();
|
||||
auto containers = serverConfig.value(config_key::containers).toArray();
|
||||
auto newServerConfig = QJsonDocument::fromJson(configStr.toUtf8()).object();
|
||||
auto containers = newServerConfig.value(config_key::containers).toArray();
|
||||
if (containers.isEmpty()) {
|
||||
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);
|
||||
container[containerName] = containerConfig;
|
||||
containers.replace(0, container);
|
||||
serverConfig[config_key::containers] = containers;
|
||||
configStr = QString(QJsonDocument(serverConfig).toJson());
|
||||
newServerConfig[config_key::containers] = containers;
|
||||
configStr = QString(QJsonDocument(newServerConfig).toJson());
|
||||
}
|
||||
|
||||
QJsonObject apiConfig = QJsonDocument::fromJson(configStr.toUtf8()).object();
|
||||
serverConfig[config_key::dns1] = apiConfig.value(config_key::dns1);
|
||||
serverConfig[config_key::dns2] = apiConfig.value(config_key::dns2);
|
||||
serverConfig[config_key::containers] = apiConfig.value(config_key::containers);
|
||||
serverConfig[config_key::hostName] = apiConfig.value(config_key::hostName);
|
||||
QJsonObject newServerConfig = QJsonDocument::fromJson(configStr.toUtf8()).object();
|
||||
serverConfig[config_key::dns1] = newServerConfig.value(config_key::dns1);
|
||||
serverConfig[config_key::dns2] = newServerConfig.value(config_key::dns2);
|
||||
serverConfig[config_key::containers] = newServerConfig.value(config_key::containers);
|
||||
serverConfig[config_key::hostName] = newServerConfig.value(config_key::hostName);
|
||||
|
||||
if (apiConfig.value(config_key::configVersion).toInt() == ApiConfigSources::AmneziaGateway) {
|
||||
serverConfig[config_key::configVersion] = apiConfig.value(config_key::configVersion);
|
||||
serverConfig[config_key::description] = apiConfig.value(config_key::description);
|
||||
serverConfig[config_key::name] = apiConfig.value(config_key::name);
|
||||
if (newServerConfig.value(config_key::configVersion).toInt() == ApiConfigSources::AmneziaGateway) {
|
||||
serverConfig[config_key::configVersion] = newServerConfig.value(config_key::configVersion);
|
||||
serverConfig[config_key::description] = newServerConfig.value(config_key::description);
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -146,6 +184,15 @@ QStringList ApiController::getProxyUrls()
|
||||
QList<QSslError> sslErrors;
|
||||
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) {
|
||||
request.setUrl(proxyStorageUrl);
|
||||
reply = amnApp->manager()->get(request);
|
||||
@@ -166,11 +213,23 @@ QStringList ApiController::getProxyUrls()
|
||||
EVP_PKEY *privateKey = nullptr;
|
||||
QByteArray responseBody;
|
||||
try {
|
||||
QByteArray key = PROD_PROXY_STORAGE_KEY;
|
||||
QSimpleCrypto::QRsa rsa;
|
||||
privateKey = rsa.getPrivateKeyFromByteArray(key, "");
|
||||
responseBody = rsa.decrypt(encryptedResponseBody, privateKey, RSA_PKCS1_PADDING);
|
||||
if (!m_isDevEnvironment) {
|
||||
QCryptographicHash hash(QCryptographicHash::Sha512);
|
||||
hash.addData(key);
|
||||
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 (...) {
|
||||
Utils::logException();
|
||||
qCritical() << "error loading private key from environment variables or decrypting payload";
|
||||
return {};
|
||||
}
|
||||
@@ -292,38 +351,44 @@ ErrorCode ApiController::getServicesList(QByteArray &responseBody)
|
||||
connect(reply, &QNetworkReply::sslErrors, [this, &sslErrors](const QList<QSslError> &errors) { sslErrors = errors; });
|
||||
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();
|
||||
std::random_device randomDevice;
|
||||
std::mt19937 generator(randomDevice());
|
||||
std::shuffle(m_proxyUrls.begin(), m_proxyUrls.end(), generator);
|
||||
for (const QString &proxyUrl : m_proxyUrls) {
|
||||
qDebug() << "Go to the next endpoint";
|
||||
request.setUrl(QString("%1v1/services").arg(proxyUrl));
|
||||
reply->deleteLater(); // delete the previous reply
|
||||
reply = amnApp->manager()->get(request);
|
||||
|
||||
QObject::connect(reply, &QNetworkReply::finished, &wait, &QEventLoop::quit);
|
||||
connect(reply, &QNetworkReply::sslErrors, [this, &sslErrors](const QList<QSslError> &errors) { sslErrors = errors; });
|
||||
wait.exec();
|
||||
if (reply->error() != QNetworkReply::NetworkError::TimeoutError
|
||||
&& reply->error() != QNetworkReply::NetworkError::OperationCanceledError) {
|
||||
|
||||
responseBody = reply->readAll();
|
||||
if (!sslErrors.isEmpty() || !shouldBypassProxy(reply, responseBody, false)) {
|
||||
break;
|
||||
}
|
||||
reply->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
responseBody = reply->readAll();
|
||||
auto errorCode = checkErrors(sslErrors, reply);
|
||||
reply->deleteLater();
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
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
|
||||
IosController::Instance()->requestInetAccess();
|
||||
QThread::msleep(10);
|
||||
#endif
|
||||
|
||||
QNetworkAccessManager manager;
|
||||
QNetworkRequest request;
|
||||
request.setTransferTimeout(7000);
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
@@ -339,6 +404,9 @@ ErrorCode ApiController::getConfigForService(const QString &installationUuid, co
|
||||
}
|
||||
apiPayload[configKey::serviceType] = serviceType;
|
||||
apiPayload[configKey::uuid] = installationUuid;
|
||||
if (!authData.isEmpty()) {
|
||||
apiPayload[configKey::authData] = authData;
|
||||
}
|
||||
|
||||
QSimpleCrypto::QBlockCipher blockCipher;
|
||||
QByteArray key = blockCipher.generatePrivateSalt(32);
|
||||
@@ -361,6 +429,7 @@ ErrorCode ApiController::getConfigForService(const QString &installationUuid, co
|
||||
QSimpleCrypto::QRsa rsa;
|
||||
publicKey = rsa.getPublicKeyFromByteArray(rsaKey);
|
||||
} catch (...) {
|
||||
Utils::logException();
|
||||
qCritical() << "error loading public key from environment variables";
|
||||
return ErrorCode::ApiMissingAgwPublicKey;
|
||||
}
|
||||
@@ -370,14 +439,16 @@ ErrorCode ApiController::getConfigForService(const QString &installationUuid, co
|
||||
|
||||
encryptedApiPayload = blockCipher.encryptAesBlockCipher(QJsonDocument(apiPayload).toJson(), key, iv, "", salt);
|
||||
} catch (...) { // todo change error handling in QSimpleCrypto?
|
||||
Utils::logException();
|
||||
qCritical() << "error when encrypting the request body";
|
||||
return ErrorCode::ApiConfigDecryptionError;
|
||||
}
|
||||
|
||||
QJsonObject requestBody;
|
||||
requestBody[configKey::keyPayload] = QString(encryptedKeyPayload.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;
|
||||
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; });
|
||||
wait.exec();
|
||||
|
||||
if (reply->error() == QNetworkReply::NetworkError::TimeoutError || reply->error() == QNetworkReply::NetworkError::OperationCanceledError) {
|
||||
if (m_proxyUrls.isEmpty()) {
|
||||
m_proxyUrls = getProxyUrls();
|
||||
}
|
||||
auto encryptedResponseBody = reply->readAll();
|
||||
|
||||
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) {
|
||||
qDebug() << "Go to the next endpoint";
|
||||
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);
|
||||
connect(reply, &QNetworkReply::sslErrors, [this, &sslErrors](const QList<QSslError> &errors) { sslErrors = errors; });
|
||||
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;
|
||||
}
|
||||
reply->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
auto errorCode = checkErrors(sslErrors, reply);
|
||||
reply->deleteLater();
|
||||
if (errorCode) {
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
auto encryptedResponseBody = reply->readAll();
|
||||
reply->deleteLater();
|
||||
try {
|
||||
auto responseBody = blockCipher.decryptAesBlockCipher(encryptedResponseBody, key, iv, "", salt);
|
||||
fillServerConfig(protocol, apiPayloadData, responseBody, serverConfig);
|
||||
} catch (...) { // todo change error handling in QSimpleCrypto?
|
||||
Utils::logException();
|
||||
qCritical() << "error when decrypting the request body";
|
||||
return ErrorCode::ApiConfigDecryptionError;
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
|
||||
@@ -21,7 +21,7 @@ public slots:
|
||||
|
||||
ErrorCode getServicesList(QByteArray &responseBody);
|
||||
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:
|
||||
void errorOccurred(ErrorCode errorCode);
|
||||
|
||||
@@ -96,6 +96,7 @@ namespace amnezia
|
||||
|
||||
// import and install errors
|
||||
ImportInvalidConfigError = 900,
|
||||
ImportOpenConfigError = 901,
|
||||
|
||||
// Android errors
|
||||
AndroidError = 1000,
|
||||
@@ -107,6 +108,7 @@ namespace amnezia
|
||||
ApiConfigTimeoutError = 1103,
|
||||
ApiConfigSslError = 1104,
|
||||
ApiMissingAgwPublicKey = 1105,
|
||||
ApiConfigDecryptionError = 1106,
|
||||
|
||||
// QFile errors
|
||||
OpenError = 1200,
|
||||
|
||||
@@ -50,6 +50,7 @@ QString errorString(ErrorCode code) {
|
||||
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::ImportOpenConfigError): errorMessage = QObject::tr("Unable to open config file"); break;
|
||||
|
||||
// Android errors
|
||||
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::ApiConfigTimeoutError): errorMessage = QObject::tr("Server response timeout on api request"); 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
|
||||
case(ErrorCode::OpenError): errorMessage = QObject::tr("QFile error: The file could not be opened"); break;
|
||||
|
||||
@@ -78,7 +78,7 @@ bool Daemon::activate(const InterfaceConfig& config) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (supportDnsUtils() && !dnsutils()->restoreResolvers()) {
|
||||
if (!dnsutils()->restoreResolvers()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -165,10 +165,6 @@ bool Daemon::activate(const InterfaceConfig& config) {
|
||||
}
|
||||
|
||||
bool Daemon::maybeUpdateResolvers(const InterfaceConfig& config) {
|
||||
if (!supportDnsUtils()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((config.m_hopType == InterfaceConfig::MultiHopExit) ||
|
||||
(config.m_hopType == InterfaceConfig::SingleHop)) {
|
||||
QList<QHostAddress> resolvers;
|
||||
@@ -423,13 +419,8 @@ bool Daemon::deactivate(bool emitSignals) {
|
||||
}
|
||||
|
||||
// Cleanup DNS
|
||||
if (supportDnsUtils() && !dnsutils()->restoreResolvers()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!wgutils()->interfaceExists()) {
|
||||
logger.warning() << "Wireguard interface does not exist.";
|
||||
return false;
|
||||
if (!dnsutils()->restoreResolvers()) {
|
||||
logger.warning() << "Failed to restore DNS resolvers.";
|
||||
}
|
||||
|
||||
// Cleanup peers and routing
|
||||
@@ -449,13 +440,9 @@ bool Daemon::deactivate(bool emitSignals) {
|
||||
}
|
||||
m_excludedAddrSet.clear();
|
||||
|
||||
// Delete the interface
|
||||
if (!wgutils()->deleteInterface()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_connections.clear();
|
||||
return true;
|
||||
// Delete the interface
|
||||
return wgutils()->deleteInterface();
|
||||
}
|
||||
|
||||
QString Daemon::logs() {
|
||||
|
||||
@@ -69,7 +69,6 @@ class Daemon : public QObject {
|
||||
virtual WireguardUtils* wgutils() const = 0;
|
||||
virtual bool supportIPUtils() const { return false; }
|
||||
virtual IPUtils* iputils() { return nullptr; }
|
||||
virtual bool supportDnsUtils() const { return false; }
|
||||
virtual DnsUtils* dnsutils() { return nullptr; }
|
||||
|
||||
static bool parseStringList(const QJsonObject& obj, const QString& name,
|
||||
|
||||
@@ -92,6 +92,17 @@ void DaemonLocalServerConnection::parseCommand(const QByteArray& data) {
|
||||
|
||||
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") {
|
||||
InterfaceConfig config;
|
||||
if (!Daemon::parseConfig(obj, config)) {
|
||||
@@ -115,8 +126,7 @@ void DaemonLocalServerConnection::parseCommand(const QByteArray& data) {
|
||||
if (type == "status") {
|
||||
QJsonObject obj = Daemon::instance()->getStatus();
|
||||
obj.insert("type", "status");
|
||||
m_socket->write(QJsonDocument(obj).toJson(QJsonDocument::Compact));
|
||||
m_socket->write("\n");
|
||||
write(obj);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -124,8 +134,7 @@ void DaemonLocalServerConnection::parseCommand(const QByteArray& data) {
|
||||
QJsonObject obj;
|
||||
obj.insert("type", "logs");
|
||||
obj.insert("logs", Daemon::instance()->logs().replace("\n", "|"));
|
||||
m_socket->write(QJsonDocument(obj).toJson(QJsonDocument::Compact));
|
||||
m_socket->write("\n");
|
||||
write(obj);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,5 +16,7 @@
|
||||
<array>
|
||||
<string>$(AppIdentifierPrefix)group.org.amnezia.AmneziaVPN</string>
|
||||
</array>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 336 B After Width: | Height: | Size: 421 B |
|
Before Width: | Height: | Size: 593 B After Width: | Height: | Size: 946 B |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 593 B After Width: | Height: | Size: 946 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 14 KiB |
@@ -1,68 +1,68 @@
|
||||
{
|
||||
"images" : [
|
||||
"images": [
|
||||
{
|
||||
"filename" : "16.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "16x16"
|
||||
"idiom": "mac",
|
||||
"size": "16x16",
|
||||
"scale": "1x",
|
||||
"filename": "16.png"
|
||||
},
|
||||
{
|
||||
"filename" : "16@2x.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "16x16"
|
||||
"idiom": "mac",
|
||||
"size": "16x16",
|
||||
"scale": "2x",
|
||||
"filename": "16@2x.png"
|
||||
},
|
||||
{
|
||||
"filename" : "32.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "32x32"
|
||||
"idiom": "mac",
|
||||
"size": "32x32",
|
||||
"scale": "1x",
|
||||
"filename": "32.png"
|
||||
},
|
||||
{
|
||||
"filename" : "32@2x.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "32x32"
|
||||
"idiom": "mac",
|
||||
"size": "32x32",
|
||||
"scale": "2x",
|
||||
"filename": "32@2x.png"
|
||||
},
|
||||
{
|
||||
"filename" : "128.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "128x128"
|
||||
"idiom": "mac",
|
||||
"size": "128x128",
|
||||
"scale": "1x",
|
||||
"filename": "128.png"
|
||||
},
|
||||
{
|
||||
"filename" : "128@2x.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "128x128"
|
||||
"idiom": "mac",
|
||||
"size": "128x128",
|
||||
"scale": "2x",
|
||||
"filename": "128@2x.png"
|
||||
},
|
||||
{
|
||||
"filename" : "256.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "256x256"
|
||||
"idiom": "mac",
|
||||
"size": "256x256",
|
||||
"scale": "1x",
|
||||
"filename": "256.png"
|
||||
},
|
||||
{
|
||||
"filename" : "256@2x.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "256x256"
|
||||
"idiom": "mac",
|
||||
"size": "256x256",
|
||||
"scale": "2x",
|
||||
"filename": "256@2x.png"
|
||||
},
|
||||
{
|
||||
"filename" : "512.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "512x512"
|
||||
"idiom": "mac",
|
||||
"size": "512x512",
|
||||
"scale": "1x",
|
||||
"filename": "512.png"
|
||||
},
|
||||
{
|
||||
"filename" : "512@2x.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "512x512"
|
||||
"idiom": "mac",
|
||||
"size": "512x512",
|
||||
"scale": "2x",
|
||||
"filename": "512@2x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
"info": {
|
||||
"version": 1,
|
||||
"author": "xcode"
|
||||
}
|
||||
}
|
||||
|
||||
BIN
client/macos/app/Images.xcassets/AppIcon.icns
Normal file
@@ -1,6 +1,68 @@
|
||||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
"images": [
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "16x16",
|
||||
"scale": "1x",
|
||||
"filename": "16.png"
|
||||
},
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "16x16",
|
||||
"scale": "2x",
|
||||
"filename": "16@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "32x32",
|
||||
"scale": "1x",
|
||||
"filename": "32.png"
|
||||
},
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "32x32",
|
||||
"scale": "2x",
|
||||
"filename": "32@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "128x128",
|
||||
"scale": "1x",
|
||||
"filename": "128.png"
|
||||
},
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "128x128",
|
||||
"scale": "2x",
|
||||
"filename": "128@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "256x256",
|
||||
"scale": "1x",
|
||||
"filename": "256.png"
|
||||
},
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "256x256",
|
||||
"scale": "2x",
|
||||
"filename": "256@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "512x512",
|
||||
"scale": "1x",
|
||||
"filename": "512.png"
|
||||
},
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "512x512",
|
||||
"scale": "2x",
|
||||
"filename": "512@2x.png"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"version": 1,
|
||||
"author": "xcode"
|
||||
}
|
||||
}
|
||||
|
||||
184
client/macos/app/Info.plist.in
Normal file
@@ -0,0 +1,184 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleAllowMixedLocalizations</key>
|
||||
<true/>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>${QT_INTERNAL_DOLLAR_VAR}{PRODUCT_NAME}</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.utilities</string>
|
||||
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
|
||||
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||
<true/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>AmneziaVPNLaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array/>
|
||||
<key>UIRequiresFullScreen</key>
|
||||
<true/>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array/>
|
||||
<key>UIUserInterfaceStyle</key>
|
||||
<string>Light</string>
|
||||
<key>com.wireguard.ios.app_group_id</key>
|
||||
<string>group.org.amnezia.AmneziaVPN</string>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<true/>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>Amnezia VPN needs access to the camera for reading QR-codes.</string>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<false/>
|
||||
<key>NSAllowsLocalNetworking</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>CFBundleIcons</key>
|
||||
<dict/>
|
||||
<key>CFBundleIcons~ipad</key>
|
||||
<dict/>
|
||||
<key>UTImportedTypeDeclarations</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>Amnezia VPN config</string>
|
||||
<key>UTTypeIconFiles</key>
|
||||
<array/>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>org.amnezia.AmneziaVPN.amnezia-config</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>vpn</string>
|
||||
</array>
|
||||
<key>public.mime-type</key>
|
||||
<array>
|
||||
<string>text/plain</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>WireGuard config</string>
|
||||
<key>UTTypeIconFiles</key>
|
||||
<array/>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>org.amnezia.AmneziaVPN.wireguard-config</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>conf</string>
|
||||
<string>cfg</string>
|
||||
</array>
|
||||
<key>public.mime-type</key>
|
||||
<array>
|
||||
<string>text/plain</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>OpenVPN config</string>
|
||||
<key>UTTypeIconFiles</key>
|
||||
<array/>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>org.amnezia.AmneziaVPN.openvpn-config</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>ovpn</string>
|
||||
</array>
|
||||
<key>public.mime-type</key>
|
||||
<array>
|
||||
<string>text/plain</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>AmneziaVPN backup file</string>
|
||||
<key>UTTypeIconFiles</key>
|
||||
<array/>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>org.amnezia.AmneziaVPN.backup-config</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>backup</string>
|
||||
</array>
|
||||
<key>public.mime-type</key>
|
||||
<array>
|
||||
<string>text/plain</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Amnezia VPN config</string>
|
||||
<key>LSHandlerRank</key>
|
||||
<string>Alternate</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>org.amnezia.AmneziaVPN.amnezia-config</string>
|
||||
<string>org.amnezia.AmneziaVPN.wireguard-config</string>
|
||||
<string>org.amnezia.AmneziaVPN.openvpn-config</string>
|
||||
<string>org.amnezia.AmneziaVPN.backup-config</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -3,40 +3,52 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.application-identifier</key>
|
||||
<string>$(DEVELOPMENT_TEAM).$(NETEXT_ID_MACOS)</string>
|
||||
|
||||
<string>X7UJ388FXK.org.amnezia.AmneziaVPN.network-extension</string>
|
||||
<key>com.apple.developer.networking.networkextension</key>
|
||||
<array>
|
||||
<string>packet-tunnel-provider</string>
|
||||
</array>
|
||||
|
||||
<key>keychain-access-groups</key>
|
||||
<array>
|
||||
<string>$(DEVELOPMENT_TEAM).*</string>
|
||||
</array>
|
||||
|
||||
<key>com.apple.developer.team-identifier</key>
|
||||
<string>$(DEVELOPMENT_TEAM)</string>
|
||||
|
||||
<key>com.apple.developer.system-extension.install</key>
|
||||
<true/>
|
||||
|
||||
<string>X7UJ388FXK</string>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<true/>
|
||||
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>$(DEVELOPMENT_TEAM).$(GROUP_ID_MACOS)</string>
|
||||
<string>group.org.amnezia.AmneziaVPN</string>
|
||||
</array>
|
||||
|
||||
<key>com.apple.security.assets.movies.read-write</key>
|
||||
<true/>
|
||||
<key>com.apple.security.assets.music.read-write</key>
|
||||
<true/>
|
||||
<key>com.apple.security.assets.pictures.read-write</key>
|
||||
<true/>
|
||||
<key>com.apple.security.device.audio-input</key>
|
||||
<true/>
|
||||
<key>com.apple.security.device.bluetooth</key>
|
||||
<true/>
|
||||
<key>com.apple.security.device.camera</key>
|
||||
<true/>
|
||||
<key>com.apple.security.device.usb</key>
|
||||
<true/>
|
||||
<key>com.apple.security.files.downloads.read-write</key>
|
||||
<true/>
|
||||
<key>com.apple.security.files.user-selected.read-write</key>
|
||||
<true/>
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
|
||||
<key>com.apple.security.network.server</key>
|
||||
<true/>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<key>com.apple.security.personal-information.addressbook</key>
|
||||
<true/>
|
||||
<key>com.apple.private.network.socket-delegate</key>
|
||||
<key>com.apple.security.personal-information.calendars</key>
|
||||
<true/>
|
||||
<key>com.apple.security.personal-information.location</key>
|
||||
<true/>
|
||||
<key>com.apple.security.print</key>
|
||||
<true/>
|
||||
<key>keychain-access-groups</key>
|
||||
<array>
|
||||
<string>$(AppIdentifierPrefix)org.amnezia.AmneziaVPN.network-extension</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
139
client/macos/networkextension/CMakeLists.txt
Normal file
@@ -0,0 +1,139 @@
|
||||
enable_language(Swift)
|
||||
message("Client message >> macos build >> networkextension")
|
||||
set(CLIENT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
|
||||
|
||||
add_executable(networkextension)
|
||||
|
||||
if(MACOS_NE)
|
||||
message("MACOS_NE is ON")
|
||||
add_definitions(-DQ_OS_IOS)
|
||||
add_definitions(-DMACOS_NE)
|
||||
else()
|
||||
message("MACOS_NE is OFF")
|
||||
endif()
|
||||
message("executable_path is: @executable_path/../../Frameworks")
|
||||
set_target_properties(networkextension PROPERTIES
|
||||
XCODE_PRODUCT_TYPE com.apple.product-type.app-extension
|
||||
BUNDLE_EXTENSION appex
|
||||
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING "${APPLE_PROJECT_VERSION}"
|
||||
MACOSX_BUNDLE_INFO_STRING "AmneziaVPNNetworkExtension"
|
||||
MACOSX_BUNDLE_BUNDLE_NAME "AmneziaVPNNetworkExtension"
|
||||
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "${BUILD_IOS_APP_IDENTIFIER}.network-extension"
|
||||
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_NAME "${BUILD_IOS_APP_IDENTIFIER}.network-extension"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS ${CMAKE_CURRENT_SOURCE_DIR}/AmneziaVPNNetworkExtension.entitlements
|
||||
XCODE_ATTRIBUTE_MARKETING_VERSION "${APP_MAJOR_VERSION}"
|
||||
XCODE_ATTRIBUTE_CURRENT_PROJECT_VERSION "${BUILD_ID}"
|
||||
XCODE_ATTRIBUTE_PRODUCT_NAME "AmneziaVPNNetworkExtension"
|
||||
|
||||
XCODE_ATTRIBUTE_APPLICATION_EXTENSION_API_ONLY "YES"
|
||||
XCODE_ATTRIBUTE_ENABLE_BITCODE "NO"
|
||||
|
||||
# XCODE_ATTRIBUTE_CODE_SIGN_STYLE Automatic
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_STYLE Manual
|
||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER "Mac AppStore AmneziaVPN.network-extension"
|
||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER[variant=Debug] "amnezia.AmneziaVPN.network-extensionManual"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Distribution: Privacy Technologies OU (X7UJ388FXK)"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY[variant=Debug] "Apple Development"
|
||||
|
||||
|
||||
XCODE_ATTRIBUTE_INFOPLIST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in
|
||||
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../../../../Frameworks @loader_path/../../../../Frameworks"
|
||||
)
|
||||
|
||||
set_target_properties(networkextension PROPERTIES
|
||||
XCODE_ATTRIBUTE_SWIFT_VERSION "5.0"
|
||||
XCODE_ATTRIBUTE_CLANG_ENABLE_MODULES "YES"
|
||||
XCODE_ATTRIBUTE_SWIFT_OBJC_BRIDGING_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/WireGuardNetworkExtension-Bridging-Header.h"
|
||||
XCODE_ATTRIBUTE_SWIFT_OPTIMIZATION_LEVEL "-Onone"
|
||||
XCODE_ATTRIBUTE_SWIFT_PRECOMPILE_BRIDGING_HEADER "NO"
|
||||
)
|
||||
|
||||
set_target_properties("networkextension" PROPERTIES
|
||||
XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "X7UJ388FXK"
|
||||
)
|
||||
|
||||
find_library(FW_ASSETS_LIBRARY AssetsLibrary)
|
||||
find_library(FW_MOBILE_CORE MobileCoreServices)
|
||||
find_library(FW_UI_KIT UIKit)
|
||||
find_library(FW_LIBRESOLV libresolv.9.tbd)
|
||||
|
||||
|
||||
# Set the root directory
|
||||
set(CLIENT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
|
||||
|
||||
set(CMAKE_FRAMEWORK_PATH ${CLIENT_ROOT_DIR}/3rd/OpenVPNAdapter/build/Release-macos)
|
||||
|
||||
target_link_libraries(networkextension PRIVATE ${FW_LIBRESOLV})
|
||||
|
||||
target_compile_options(networkextension PRIVATE -DGROUP_ID=\"${BUILD_IOS_GROUP_IDENTIFIER}\")
|
||||
target_compile_options(networkextension PRIVATE -DNETWORK_EXTENSION=1)
|
||||
|
||||
set(WG_APPLE_SOURCE_DIR ${CLIENT_ROOT_DIR}/3rd/amneziawg-apple/Sources)
|
||||
|
||||
message("WG_APPLE_SOURCE_DIR is: ${WG_APPLE_SOURCE_DIR}")
|
||||
message("CLIENT_ROOT_DIR is: ${CLIENT_ROOT_DIR}")
|
||||
|
||||
target_sources(networkextension PRIVATE
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/WireGuardAdapter.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/PacketTunnelSettingsGenerator.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/DNSResolver.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardNetworkExtension/ErrorNotifier.swift
|
||||
${WG_APPLE_SOURCE_DIR}/Shared/Keychain.swift
|
||||
${WG_APPLE_SOURCE_DIR}/Shared/Model/TunnelConfiguration+WgQuickConfig.swift
|
||||
${WG_APPLE_SOURCE_DIR}/Shared/Model/NETunnelProviderProtocol+Extension.swift
|
||||
${WG_APPLE_SOURCE_DIR}/Shared/Model/String+ArrayConversion.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/TunnelConfiguration.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/IPAddressRange.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/Endpoint.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/DNSServer.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/InterfaceConfiguration.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/PeerConfiguration.swift
|
||||
${WG_APPLE_SOURCE_DIR}/Shared/FileManager+Extension.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKitC/x25519.c
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/Array+ConcurrentMap.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/IPAddress+AddrInfo.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/PrivateKey.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/HevSocksTunnel.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/NELogController.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/Log.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/LogRecord.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+WireGuard.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+OpenVPN.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+Xray.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/WGConfig.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/iosglue.mm
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/XrayConfig.swift
|
||||
)
|
||||
|
||||
target_sources(networkextension PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/PrivacyInfo.xcprivacy
|
||||
)
|
||||
|
||||
set_property(TARGET networkextension APPEND PROPERTY RESOURCE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/PrivacyInfo.xcprivacy
|
||||
)
|
||||
|
||||
## Build wireguard-go-version.h
|
||||
execute_process(
|
||||
COMMAND go list -m golang.zx2c4.com/wireguard
|
||||
WORKING_DIRECTORY ${CLIENT_ROOT_DIR}/3rd/wireguard-apple/Sources/WireGuardKitGo
|
||||
OUTPUT_VARIABLE WG_VERSION_FULL
|
||||
)
|
||||
string(REGEX REPLACE ".*v\([0-9.]*\).*" "\\1" WG_VERSION_STRING 1.1.1)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/wireguard-go-version.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/wireguard-go-version.h)
|
||||
target_sources(networkextension PRIVATE
|
||||
${CMAKE_CURRENT_BINARY_DIR}/wireguard-go-version.h)
|
||||
|
||||
target_include_directories(networkextension PRIVATE ${CLIENT_ROOT_DIR})
|
||||
target_include_directories(networkextension PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
target_link_libraries(networkextension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/wireguard/macos/x86_64/libwg-go.a)
|
||||
|
||||
message(${CLIENT_ROOT_DIR})
|
||||
message(${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/xray/HevSocks5Tunnel.xcframework/macos-arm64_x86_64/libhev-socks5-tunnel.a)
|
||||
target_link_libraries(networkextension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/xray/HevSocks5Tunnel.xcframework/macos-arm64_x86_64/libhev-socks5-tunnel.a)
|
||||
|
||||
target_include_directories(networkextension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/xray/HevSocks5Tunnel.xcframework/macos-arm64_x86_64/Headers)
|
||||
@@ -3,27 +3,32 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>AmneziaVPNNetworkExtension</string>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<string>AmneziaVPNNetworkExtension</string>
|
||||
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<string>org.amnezia.AmneziaVPN.network-extension</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<string>AmneziaVPNNetworkExtension</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(MARKETING_VERSION)</string>
|
||||
<string>${APPLE_PROJECT_VERSION}</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<string>${CMAKE_PROJECT_VERSION_TWEAK}</string>
|
||||
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string>
|
||||
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>AmneziaVPNNetworkExtension</string>
|
||||
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
@@ -31,5 +36,11 @@
|
||||
<key>NSExtensionPrincipalClass</key>
|
||||
<string>$(PRODUCT_MODULE_NAME).PacketTunnelProvider</string>
|
||||
</dict>
|
||||
|
||||
<key>com.wireguard.ios.app_group_id</key>
|
||||
<string>group.org.amnezia.AmneziaVPN</string>
|
||||
|
||||
<key>com.wireguard.macos.app_group_id</key>
|
||||
<string>${BUILD_VPN_DEVELOPMENT_TEAM}.group.org.amnezia.AmneziaVPN</string>
|
||||
</dict>
|
||||
</plist>
|
||||
25
client/macos/networkextension/PrivacyInfo.xcprivacy
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPITypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>1C8F.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>C617.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,10 +1,10 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "macos/gobridge/wireguard.h"
|
||||
|
||||
#include "wireguard-go-version.h"
|
||||
#include "3rd/awg-apple/Sources/WireGuardKitC/WireGuardKitC.h"
|
||||
#include "3rd/amneziawg-apple/Sources/WireGuardKitGo/wireguard.h"
|
||||
#include "3rd/amneziawg-apple/Sources/WireGuardKitC/WireGuardKitC.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
@@ -23,3 +23,8 @@ bool key_from_hex(uint8_t key[WG_KEY_LEN], const char* hex);
|
||||
bool key_eq(const uint8_t key1[WG_KEY_LEN], const uint8_t key2[WG_KEY_LEN]);
|
||||
|
||||
void write_msg_to_log(const char* tag, const char* msg);
|
||||
|
||||
// init function definition in C
|
||||
void hev_socks5_tunnel_quit(void);
|
||||
// Updated function definition in C
|
||||
int hev_socks5_tunnel_main(const char* configFile, int fd);
|
||||
|
||||
3
client/macos/networkextension/wireguard-go-version.h.in
Normal file
@@ -0,0 +1,3 @@
|
||||
#ifndef WIREGUARD_GO_VERSION
|
||||
#define WIREGUARD_GO_VERSION "@WG_VERSION_STRING@"
|
||||
#endif // WIREGUARD_GO_VERSION
|
||||
36
client/macos/scripts/openvpn.sh
Normal file
@@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
|
||||
XCODEBUILD="/usr/bin/xcodebuild"
|
||||
WORKINGDIR=`pwd`
|
||||
PATCH="/usr/bin/patch"
|
||||
|
||||
echo "Building OpenVPNAdapter for macOS Network Extension (MacNE)..."
|
||||
|
||||
# Copy the Project-MacNE.xcconfig settings to amnezia.xcconfig
|
||||
cat $WORKINGDIR/3rd/OpenVPNAdapter/Configuration/Project-MacNE.xcconfig > $WORKINGDIR/3rd/OpenVPNAdapter/Configuration/amnezia.xcconfig
|
||||
|
||||
# Append macOS-specific build directory configurations to amnezia.xcconfig
|
||||
cat << EOF >> $WORKINGDIR/3rd/OpenVPNAdapter/Configuration/amnezia.xcconfig
|
||||
PROJECT_TEMP_DIR = $WORKINGDIR/3rd/OpenVPNAdapter/build/OpenVPNAdapter.build
|
||||
CONFIGURATION_BUILD_DIR = $WORKINGDIR/3rd/OpenVPNAdapter/build/Release-macos
|
||||
BUILT_PRODUCTS_DIR = $WORKINGDIR/3rd/OpenVPNAdapter/build/Release-macos
|
||||
EOF
|
||||
|
||||
# Fetch the current macOS SDK version dynamically
|
||||
MACOSX_SDK=$(xcrun --sdk macosx --show-sdk-path | sed -E 's/.*MacOSX([0-9]+\.[0-9]+)\.sdk/\1/')
|
||||
|
||||
echo "Using macOS SDK version: $MACOSX_SDK"
|
||||
|
||||
cd 3rd/OpenVPNAdapter
|
||||
|
||||
# Build for macOS using the correct SDK and destination
|
||||
if $XCODEBUILD -scheme OpenVPNAdapter -configuration Release -xcconfig Configuration/amnezia.xcconfig -sdk macosx$MACOSX_SDK -destination 'generic/platform=macOS' -project OpenVPNAdapter.xcodeproj ; then
|
||||
echo "OpenVPNAdapter built successfully for macOS Network Extension (MacNE)"
|
||||
else
|
||||
echo "OpenVPNAdapter macOS Network Extension (MacNE) build failed..."
|
||||
fi
|
||||
|
||||
# Remove CodeSignature if needed for macOS
|
||||
rm -rf ./build/Release-macos/OpenVPNAdapter.framework/Versions/A/_CodeSignature
|
||||
|
||||
cd ../../
|
||||
@@ -15,13 +15,24 @@
|
||||
#include "platforms/ios/QtAppDelegate-C-Interface.h"
|
||||
#endif
|
||||
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||
bool isAnotherInstanceRunning()
|
||||
{
|
||||
QLocalSocket socket;
|
||||
socket.connectToServer("AmneziaVPNInstance");
|
||||
if (socket.waitForConnected(500)) {
|
||||
qWarning() << "AmneziaVPN is already running";
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
Migrations migrationsManager;
|
||||
migrationsManager.doMigrations();
|
||||
|
||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true);
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
AllowSetForegroundWindow(ASFW_ANY);
|
||||
#endif
|
||||
@@ -32,16 +43,14 @@ int main(int argc, char *argv[])
|
||||
qputenv("ANDROID_OPENSSL_SUFFIX", "_3");
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||
AmneziaApplication app(argc, argv);
|
||||
#else
|
||||
AmneziaApplication app(argc, argv, true,
|
||||
SingleApplication::Mode::User | SingleApplication::Mode::SecondaryNotification);
|
||||
|
||||
if (!app.isPrimary()) {
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||
if (isAnotherInstanceRunning()) {
|
||||
QTimer::singleShot(1000, &app, [&]() { app.quit(); });
|
||||
return app.exec();
|
||||
}
|
||||
app.startLocalServer();
|
||||
#endif
|
||||
|
||||
// Allow to raise app window if secondary instance launched
|
||||
|
||||
@@ -34,8 +34,8 @@ LocalSocketController::LocalSocketController() {
|
||||
m_socket = new QLocalSocket(this);
|
||||
connect(m_socket, &QLocalSocket::connected, this,
|
||||
&LocalSocketController::daemonConnected);
|
||||
connect(m_socket, &QLocalSocket::disconnected, this,
|
||||
&LocalSocketController::disconnected);
|
||||
connect(m_socket, &QLocalSocket::disconnected, this,
|
||||
[&] { errorOccurred(QLocalSocket::PeerClosedError); });
|
||||
connect(m_socket, &QLocalSocket::errorOccurred, this,
|
||||
&LocalSocketController::errorOccurred);
|
||||
connect(m_socket, &QLocalSocket::readyRead, this,
|
||||
|
||||
@@ -47,7 +47,7 @@ extension PacketTunnelProvider {
|
||||
let configuration = OpenVPNConfiguration()
|
||||
configuration.fileContent = ovpnConfiguration
|
||||
if str.contains("cloak") {
|
||||
configuration.setPTCloak()
|
||||
configuration.setPTCloak()
|
||||
}
|
||||
|
||||
let evaluation: OpenVPNConfigurationEvaluation?
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#if !MACOS_NE
|
||||
#include "QRCodeReaderBase.h"
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
@@ -108,3 +109,19 @@ void QRCodeReader::startReading() {
|
||||
void QRCodeReader::stopReading() {
|
||||
[m_qrCodeReader stopReading];
|
||||
}
|
||||
#else
|
||||
#include "QRCodeReaderBase.h"
|
||||
|
||||
QRCodeReader::QRCodeReader()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QRect QRCodeReader::cameraSize() {
|
||||
return QRect();
|
||||
}
|
||||
|
||||
void QRCodeReader::startReading() {}
|
||||
void QRCodeReader::stopReading() {}
|
||||
void QRCodeReader::setCameraSize(QRect) {}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#if !MACOS_NE
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#endif
|
||||
@interface QIOSApplicationDelegate
|
||||
@end
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
|
||||
@implementation QIOSApplicationDelegate (AmneziaVPNDelegate)
|
||||
|
||||
#if !MACOS_NE
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
[application setMinimumBackgroundFetchInterval: UIApplicationBackgroundFetchIntervalMinimum];
|
||||
@@ -57,5 +57,5 @@
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
#endif
|
||||
@end
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
#if MACOS_NE
|
||||
public func toggleScreenshots(_ isEnabled: Bool) {
|
||||
|
||||
}
|
||||
|
||||
class ScreenProtection {
|
||||
|
||||
|
||||
}
|
||||
#else
|
||||
import UIKit
|
||||
|
||||
public func toggleScreenshots(_ isEnabled: Bool) {
|
||||
@@ -85,3 +95,4 @@ struct ProtectionPair {
|
||||
textField.removeFromSuperview()
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -27,6 +27,7 @@ const char* MessageKey::isOnDemand = "is-on-demand";
|
||||
const char* MessageKey::SplitTunnelType = "SplitTunnelType";
|
||||
const char* MessageKey::SplitTunnelSites = "SplitTunnelSites";
|
||||
|
||||
#if !MACOS_NE
|
||||
static UIViewController* getViewController() {
|
||||
NSArray *windows = [[UIApplication sharedApplication]windows];
|
||||
for (UIWindow *window in windows) {
|
||||
@@ -36,6 +37,7 @@ static UIViewController* getViewController() {
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
#endif
|
||||
|
||||
Vpn::ConnectionState iosStatusToState(NEVPNStatus status) {
|
||||
switch (status) {
|
||||
@@ -789,14 +791,14 @@ bool IosController::shareText(const QStringList& filesToSend) {
|
||||
NSURL *logFileUrl = [[NSURL alloc] initFileURLWithPath:filesToSend[i].toNSString()];
|
||||
[sharingItems addObject:logFileUrl];
|
||||
}
|
||||
|
||||
#if !MACOS_NE
|
||||
UIViewController *qtController = getViewController();
|
||||
if (!qtController) return;
|
||||
|
||||
UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:sharingItems applicationActivities:nil];
|
||||
|
||||
#endif
|
||||
__block bool isAccepted = false;
|
||||
|
||||
#if !MACOS_NE
|
||||
[activityController setCompletionWithItemsHandler:^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) {
|
||||
isAccepted = completed;
|
||||
emit finished();
|
||||
@@ -808,7 +810,7 @@ bool IosController::shareText(const QStringList& filesToSend) {
|
||||
popController.sourceView = qtController.view;
|
||||
popController.sourceRect = CGRectMake(100, 100, 100, 100);
|
||||
}
|
||||
|
||||
#endif
|
||||
QEventLoop wait;
|
||||
QObject::connect(this, &IosController::finished, &wait, &QEventLoop::quit);
|
||||
wait.exec();
|
||||
@@ -817,6 +819,7 @@ bool IosController::shareText(const QStringList& filesToSend) {
|
||||
}
|
||||
|
||||
QString IosController::openFile() {
|
||||
#if !MACOS_NE
|
||||
UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[@"public.item"] inMode:UIDocumentPickerModeOpen];
|
||||
|
||||
DocumentPickerDelegate *documentPickerDelegate = [[DocumentPickerDelegate alloc] init];
|
||||
@@ -826,9 +829,9 @@ QString IosController::openFile() {
|
||||
if (!qtController) return;
|
||||
|
||||
[qtController presentViewController:documentPicker animated:YES completion:nil];
|
||||
|
||||
#endif
|
||||
__block QString filePath;
|
||||
|
||||
#if !MACOS_NE
|
||||
documentPickerDelegate.documentPickerClosedCallback = ^(NSString *path) {
|
||||
if (path) {
|
||||
filePath = QString::fromUtf8(path.UTF8String);
|
||||
@@ -837,7 +840,7 @@ QString IosController::openFile() {
|
||||
}
|
||||
emit finished();
|
||||
};
|
||||
|
||||
#endif
|
||||
QEventLoop wait;
|
||||
QObject::connect(this, &IosController::finished, &wait, &QEventLoop::quit);
|
||||
wait.exec();
|
||||
@@ -863,3 +866,4 @@ void IosController::requestInetAccess() {
|
||||
}];
|
||||
[task resume];
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
#import <NetworkExtension/NetworkExtension.h>
|
||||
#import <NetworkExtension/NETunnelProviderSession.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#if !MACOS_NE
|
||||
#include <UIKit/UIKit.h>
|
||||
#endif
|
||||
|
||||
#include <Security/Security.h>
|
||||
|
||||
class IosController;
|
||||
@@ -17,9 +21,10 @@ class IosController;
|
||||
@end
|
||||
|
||||
typedef void (^DocumentPickerClosedCallback)(NSString *path);
|
||||
|
||||
#if !MACOS_NE
|
||||
@interface DocumentPickerDelegate : NSObject <UIDocumentPickerDelegate>
|
||||
|
||||
@property (nonatomic, copy) DocumentPickerClosedCallback documentPickerClosedCallback;
|
||||
|
||||
@end
|
||||
#endif
|
||||
|
||||
@@ -26,7 +26,8 @@
|
||||
|
||||
@end
|
||||
|
||||
@implementation DocumentPickerDelegate
|
||||
#if !MACOS_NE
|
||||
@implementation DocumentPickerDelegate
|
||||
|
||||
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls {
|
||||
for (NSURL *url in urls) {
|
||||
@@ -42,4 +43,5 @@
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@end
|
||||
#endif
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
#import <UserNotifications/UserNotifications.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#if !MACOS_NE
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface IOSNotificationDelegate
|
||||
@@ -87,3 +89,86 @@ void IOSNotificationHandler::notify(NotificationHandler::Message type, const QSt
|
||||
}
|
||||
}];
|
||||
}
|
||||
#else
|
||||
|
||||
// Removed the UIResponder and UIApplicationDelegate references as these are not available in macOS
|
||||
@interface IOSNotificationDelegate
|
||||
: NSObject <UNUserNotificationCenterDelegate> {
|
||||
IOSNotificationHandler* m_iosNotificationHandler;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation IOSNotificationDelegate
|
||||
|
||||
- (id)initWithObject:(IOSNotificationHandler*)notification {
|
||||
self = [super init]; // Removed `super init` as it refers to UIResponder, which is iOS specific
|
||||
if (self) {
|
||||
m_iosNotificationHandler = notification;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)userNotificationCenter:(UNUserNotificationCenter*)center
|
||||
willPresentNotification:(UNNotification*)notification
|
||||
withCompletionHandler:
|
||||
(void (^)(UNNotificationPresentationOptions options))completionHandler {
|
||||
Q_UNUSED(center)
|
||||
completionHandler(UNNotificationPresentationOptionList | UNNotificationPresentationOptionBanner);
|
||||
}
|
||||
|
||||
- (void)userNotificationCenter:(UNUserNotificationCenter*)center
|
||||
didReceiveNotificationResponse:(UNNotificationResponse*)response
|
||||
withCompletionHandler:(void (^)())completionHandler {
|
||||
Q_UNUSED(center)
|
||||
Q_UNUSED(response)
|
||||
completionHandler();
|
||||
}
|
||||
@end
|
||||
|
||||
IOSNotificationHandler::IOSNotificationHandler(QObject* parent) : NotificationHandler(parent) {
|
||||
|
||||
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
[center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert |
|
||||
UNAuthorizationOptionBadge)
|
||||
completionHandler:^(BOOL granted, NSError* _Nullable error) {
|
||||
Q_UNUSED(granted);
|
||||
if (!error) {
|
||||
m_delegate = [[IOSNotificationDelegate alloc] initWithObject:this];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
IOSNotificationHandler::~IOSNotificationHandler() { }
|
||||
|
||||
void IOSNotificationHandler::notify(NotificationHandler::Message type, const QString& title,
|
||||
const QString& message, int timerMsec) {
|
||||
Q_UNUSED(type);
|
||||
|
||||
if (!m_delegate) {
|
||||
return;
|
||||
}
|
||||
|
||||
UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
|
||||
content.title = title.toNSString();
|
||||
content.body = message.toNSString();
|
||||
content.sound = [UNNotificationSound defaultSound];
|
||||
|
||||
int timerSec = timerMsec / 1000;
|
||||
UNTimeIntervalNotificationTrigger* trigger =
|
||||
[UNTimeIntervalNotificationTrigger triggerWithTimeInterval:timerSec repeats:NO];
|
||||
|
||||
UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:@"amneziavpn"
|
||||
content:content
|
||||
trigger:trigger];
|
||||
|
||||
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
center.delegate = (id<UNUserNotificationCenterDelegate>)m_delegate;
|
||||
|
||||
[center addNotificationRequest:request
|
||||
withCompletionHandler:^(NSError* _Nullable error) {
|
||||
if (error) {
|
||||
NSLog(@"Local Notification failed");
|
||||
}
|
||||
}];
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -22,7 +22,6 @@ class LinuxDaemon final : public Daemon {
|
||||
|
||||
protected:
|
||||
WireguardUtils* wgutils() const override { return m_wgutils; }
|
||||
bool supportDnsUtils() const override { return true; }
|
||||
DnsUtils* dnsutils() override { return m_dnsutils; }
|
||||
bool supportIPUtils() const override { return true; }
|
||||
IPUtils* iputils() override { return m_iputils; }
|
||||
|
||||
@@ -21,7 +21,6 @@ class MacOSDaemon final : public Daemon {
|
||||
|
||||
protected:
|
||||
WireguardUtils* wgutils() const override { return m_wgutils; }
|
||||
bool supportDnsUtils() const override { return true; }
|
||||
DnsUtils* dnsutils() override { return m_dnsutils; }
|
||||
bool supportIPUtils() const override { return true; }
|
||||
IPUtils* iputils() override { return m_iputils; }
|
||||
|
||||
@@ -26,7 +26,6 @@ class WindowsDaemon final : public Daemon {
|
||||
protected:
|
||||
bool run(Op op, const InterfaceConfig& config) override;
|
||||
WireguardUtils* wgutils() const override { return m_wgutils; }
|
||||
bool supportDnsUtils() const override { return true; }
|
||||
DnsUtils* dnsutils() override { return m_dnsutils; }
|
||||
|
||||
private:
|
||||
|
||||
@@ -502,7 +502,7 @@ QString WindowsSplitTunnel::convertPath(const QString& path) {
|
||||
// device should contain : for e.g C:
|
||||
return "";
|
||||
}
|
||||
QByteArray buffer(2048, 0xFF);
|
||||
QByteArray buffer(2048, 0xFFu);
|
||||
auto ok = QueryDosDeviceW(qUtf16Printable(driveLetter),
|
||||
(wchar_t*)buffer.data(), buffer.size() / 2);
|
||||
|
||||
|
||||
@@ -248,7 +248,7 @@ bool WireguardUtilsWindows::updateRoutePrefix(const IPAddress& prefix) {
|
||||
}
|
||||
if (result != NO_ERROR) {
|
||||
logger.error() << "Failed to create route to"
|
||||
<< logger.sensitive(prefix.toString())
|
||||
<< prefix.toString()
|
||||
<< "result:" << result;
|
||||
}
|
||||
return result == NO_ERROR;
|
||||
@@ -265,7 +265,7 @@ bool WireguardUtilsWindows::deleteRoutePrefix(const IPAddress& prefix) {
|
||||
}
|
||||
if (result != NO_ERROR) {
|
||||
logger.error() << "Failed to delete route to"
|
||||
<< logger.sensitive(prefix.toString())
|
||||
<< prefix.toString()
|
||||
<< "result:" << result;
|
||||
}
|
||||
return result == NO_ERROR;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "platforms/windows/windowsutils.h"
|
||||
|
||||
constexpr const char* VPN_NAME = "AmneziaVPN";
|
||||
constexpr const char* WIREGUARD_DIR = "WireGuard";
|
||||
constexpr const char* WIREGUARD_DIR = "AmneziaWG";
|
||||
constexpr const char* DATA_DIR = "Data";
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "core/errorstrings.h"
|
||||
#include "vpnprotocol.h"
|
||||
|
||||
#if defined(Q_OS_WINDOWS) || defined(Q_OS_MACX) || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
#if defined(Q_OS_WINDOWS) || defined(Q_OS_MACX) and !defined MACOS_NE || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
#include "openvpnovercloakprotocol.h"
|
||||
#include "openvpnprotocol.h"
|
||||
#include "shadowsocksvpnprotocol.h"
|
||||
@@ -109,7 +109,7 @@ VpnProtocol *VpnProtocol::factory(DockerContainer container, const QJsonObject &
|
||||
#if defined(Q_OS_WINDOWS)
|
||||
case DockerContainer::Ipsec: return new Ikev2Protocol(configuration);
|
||||
#endif
|
||||
#if defined(Q_OS_WINDOWS) || defined(Q_OS_MACX) || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
#if defined(Q_OS_WINDOWS) || defined(Q_OS_MACX) and !defined MACOS_NE || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
case DockerContainer::OpenVpn: return new OpenVpnProtocol(configuration);
|
||||
case DockerContainer::Cloak: return new OpenVpnOverCloakProtocol(configuration);
|
||||
case DockerContainer::ShadowSocks: return new ShadowSocksVpnProtocol(configuration);
|
||||
|
||||
@@ -89,60 +89,60 @@
|
||||
<name>ConnectionController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.h" line="80"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="100"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="115"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="121"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="103"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="118"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="124"/>
|
||||
<source>Connect</source>
|
||||
<translation>اتصل</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="214"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="217"/>
|
||||
<source>VPN Protocols is not installed.
|
||||
Please install VPN container at first</source>
|
||||
<translation>لم يتم تثبيت بروتوكولات VPN, من فضلك قم بتنزيل حاوية VPN اولاً</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="81"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="84"/>
|
||||
<source>Connecting...</source>
|
||||
<translation>اتصال...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="86"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="89"/>
|
||||
<source>Connected</source>
|
||||
<translation>تم الاتصال</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="95"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="98"/>
|
||||
<source>Reconnecting...</source>
|
||||
<translation>إعادة الاتصال...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="105"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="108"/>
|
||||
<source>Disconnecting...</source>
|
||||
<translation>إنهاء الاتصال...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="110"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="113"/>
|
||||
<source>Preparing...</source>
|
||||
<translation>جاري التحضير...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="132"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<source>Settings updated successfully, reconnnection...</source>
|
||||
<translation>تم تحديث الاعدادات بنجاح, جاري إعادة الاتصال...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="138"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>تم تحديث الاعدادات بنجاح</translation>
|
||||
</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>
|
||||
<translation>البروتوكول المحدد غير مدعوم علي المنصة الحالية</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="233"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="236"/>
|
||||
<source>unable to create configuration</source>
|
||||
<translation>غير قادر علي إنشاء تكوين</translation>
|
||||
</message>
|
||||
@@ -253,23 +253,20 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>ImportController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="87"/>
|
||||
<source>Unable to open file</source>
|
||||
<translation>غير قادر علي فتح الملف</translation>
|
||||
<translation type="vanished">غير قادر علي فتح الملف</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="187"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="192"/>
|
||||
<source>Invalid configuration file</source>
|
||||
<translation>ملف تكوين غير صحيح</translation>
|
||||
<translation type="vanished">ملف تكوين غير صحيح</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="617"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="623"/>
|
||||
<source>Scanned %1 of %2.</source>
|
||||
<translation>تم فحص%1 من %2.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="652"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="658"/>
|
||||
<source>In the imported configuration, potentially dangerous lines were found:</source>
|
||||
<translation>في التكوين المستورد، تم العثور على سطور يحتمل أن تكون خطرة:</translation>
|
||||
</message>
|
||||
@@ -277,24 +274,24 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>InstallController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="181"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="157"/>
|
||||
<source>%1 installed successfully. </source>
|
||||
<translation>%1 تم التثبيت بنجاح. </translation>
|
||||
</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>
|
||||
<translation>%1 بالفعل مٌثبت علي الخادم. </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="203"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="179"/>
|
||||
<source>
|
||||
Added containers that were already installed on the server</source>
|
||||
<translation>
|
||||
تمت إضافة الحاويات التي كانت مٌثبتة بالفعل علي الخادم</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="283"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="259"/>
|
||||
<source>
|
||||
Already installed containers were found on the server. All installed containers have been added to the application</source>
|
||||
<translation>
|
||||
@@ -302,62 +299,62 @@ Already installed containers were found on the server. All installed containers
|
||||
تمت إضافة جميع الحاويات المٌثبتة إلي التطبيق</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="541"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="517"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>تم تحديث الاعدادات بنجاح</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="558"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="534"/>
|
||||
<source>Server '%1' was rebooted</source>
|
||||
<translation>تمت إعادة تشغيل الخادم%1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="570"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="546"/>
|
||||
<source>Server '%1' was removed</source>
|
||||
<translation>تمت إزالة الخادم '%1'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="581"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="557"/>
|
||||
<source>All containers from server '%1' have been removed</source>
|
||||
<translation>قد تم حذفها '%1' جميع الحاويات من الخادم</translation>
|
||||
</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 '%2'</source>
|
||||
<translation>%1 تم حدف '%2' اسم الخادم</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="608"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="584"/>
|
||||
<source>Api config removed</source>
|
||||
<translation>تم حذف تكوين Api</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="630"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="606"/>
|
||||
<source>%1 cached profile cleared</source>
|
||||
<translation>تم مسح ملف تعريف %1 المخزن مؤقتًا</translation>
|
||||
</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>
|
||||
<translation>من فضلك قم بتسجيل الدخول كمستخدم</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="797"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="773"/>
|
||||
<source>Server added successfully</source>
|
||||
<translation>تمت إضافة الخادم بنجاح</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="845"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="821"/>
|
||||
<source>%1 installed successfully.</source>
|
||||
<translation>تم تحميل %1 بنجاح</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="877"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="855"/>
|
||||
<source>API config reloaded</source>
|
||||
<translation>تمت إعادة تحميل تكوين API</translation>
|
||||
</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>
|
||||
<translation>تم تغيير بلد الاتصال بنجاح إلى %1</translation>
|
||||
</message>
|
||||
@@ -401,28 +398,28 @@ Already installed containers were found on the server. All installed containers
|
||||
<context>
|
||||
<name>NotificationHandler</name>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="63"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="70"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<source>AmneziaVPN</source>
|
||||
<translation>AmneziaVPN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="65"/>
|
||||
<source>VPN Connected</source>
|
||||
<translation>تم الاتصال</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="72"/>
|
||||
<source>VPN Disconnected</source>
|
||||
<translation>تم إنهاء الاتصال</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="94"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<source>AmneziaVPN notification</source>
|
||||
<translation>إشعار من AmneziaVPN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="96"/>
|
||||
<source>Unsecured network detected: </source>
|
||||
<translation>تم العثور علي شبكة غير مؤمنة: </translation>
|
||||
</message>
|
||||
@@ -2318,97 +2315,107 @@ Already installed containers were found on the server. All installed containers
|
||||
<context>
|
||||
<name>PageSetupWizardConfigSource</name>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
|
||||
<source>Connection</source>
|
||||
<translation>الاتصال</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
|
||||
<source>Settings</source>
|
||||
<translation type="unfinished">إعدادات</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
|
||||
<source>Enable logs</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<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>
|
||||
<translation>أدخل المفتاح، أضف ملف تكوين أو امسح رمز الاستجابة السريعة</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="122"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="150"/>
|
||||
<source>Insert key</source>
|
||||
<translation>أدخل مفتاح</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="151"/>
|
||||
<source>Insert</source>
|
||||
<translation>أدخل</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
|
||||
<source>Continue</source>
|
||||
<translation>واصل</translation>
|
||||
</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>
|
||||
<translation>اختيارات اتصال اخري</translation>
|
||||
</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>
|
||||
<translation>VPN بواسطة Amnezia</translation>
|
||||
</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>
|
||||
<translation>اتصل بخدمات VPN الكلاسيكية المدفوعة والمجانية من Amnezia</translation>
|
||||
</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>
|
||||
<translation>VPN ذاتية الاستضافة</translation>
|
||||
</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>
|
||||
<translation>قم بتكوين Amnezia VPN على الخادم الخاص بك</translation>
|
||||
</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>
|
||||
<translation>استرجاع من ملف يحتوي علي نسخة احتياطية</translation>
|
||||
</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>
|
||||
<translation>افتح ملف نسخ احتياطي</translation>
|
||||
</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>
|
||||
<translation>ملفات نٌسخ احتياطية (*.backup)</translation>
|
||||
</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>
|
||||
<translation>ملف إعدادات اتصال</translation>
|
||||
</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>
|
||||
<translation>افتح ملف تكوين</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
|
||||
<source>QR code</source>
|
||||
<translation>رمز QR</translation>
|
||||
</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>
|
||||
<translation>ليس لدي اي شئ</translation>
|
||||
</message>
|
||||
@@ -2426,12 +2433,12 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>عنوان خادم IP [:منفذ]</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="116"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="113"/>
|
||||
<source>Continue</source>
|
||||
<translation>واصل</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="144"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="141"/>
|
||||
<source>All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>ستظل جميع البيانات التي تدخلها سرية للغاية ولن تتم مشاركتها أو الكشف عنها ل Amnezia أو أي طرف ثالث</translation>
|
||||
</message>
|
||||
@@ -2441,42 +2448,42 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="78"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="75"/>
|
||||
<source>SSH Username</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="94"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="91"/>
|
||||
<source>Password or SSH private key</source>
|
||||
<translation>كلمة مرور او مفتاح SSH خاص</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="153"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="150"/>
|
||||
<source>How to run your VPN server</source>
|
||||
<translation>كيف تقوم بتشغيل خادم ال VPN الخاص بك</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="154"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="151"/>
|
||||
<source>Where to get connection data, step-by-step instructions for buying a VPS</source>
|
||||
<translation>اين تحصل علي بيانات الاتصال, تعليمات خطوة ب خطوة لشراء VPS</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="167"/>
|
||||
<source>Ip address cannot be empty</source>
|
||||
<translation>لا يمكن لعنوان IP ان يكون فارغ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="173"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<source>Enter the address in the format 255.255.255.255:88</source>
|
||||
<translation>ادخل العنوان في شكل 255.255.255.255:88</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="177"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="174"/>
|
||||
<source>Login cannot be empty</source>
|
||||
<translation>تسجيل دخول لا يمكن ان يكون فارغ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="181"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="178"/>
|
||||
<source>Password/private key cannot be empty</source>
|
||||
<translation>كلمة مرور/مفتاح خاص لأ يمكن ان يكونو فارغين</translation>
|
||||
</message>
|
||||
@@ -2771,62 +2778,67 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>ابحث</translation>
|
||||
</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>
|
||||
<translation>تاريخ الإنشاء: %1</translation>
|
||||
</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>
|
||||
<translation>اخر تصافح: %1</translation>
|
||||
</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>
|
||||
<translation>البيانات المستلمة: %1</translation>
|
||||
</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>
|
||||
<translation>البيانات المٌرسلة: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="862"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
|
||||
<source>Allowed IPs: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
|
||||
<source>Rename</source>
|
||||
<translation>إعادة التسمية</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="908"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
|
||||
<source>Client name</source>
|
||||
<translation>اسم العميل</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="921"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
|
||||
<source>Save</source>
|
||||
<translation>احفظ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="955"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<source>Revoke</source>
|
||||
<translation>سحب وإبطال</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="959"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
|
||||
<source>Revoke the config for a user - %1?</source>
|
||||
<translation>سحب وإبطال للمستخدم - %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
|
||||
<source>The user will no longer be able to connect to your server.</source>
|
||||
<translation>المستخدم لن يكون قادر علي الاتصال بعد الان.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="961"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
|
||||
<source>Continue</source>
|
||||
<translation>واصل</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="962"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
|
||||
<source>Cancel</source>
|
||||
<translation>إلغاء</translation>
|
||||
</message>
|
||||
@@ -2939,17 +2951,17 @@ Already installed containers were found on the server. All installed containers
|
||||
<context>
|
||||
<name>PageStart</name>
|
||||
<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>
|
||||
<translation>تم تعطيل التسجيل بعد 14 يومًا، وتم حذف ملفات السجل</translation>
|
||||
</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>
|
||||
<translation>تم تحميل الإعدادات من ملف نسخة احتياطية</translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -3288,22 +3300,22 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>انتهت مدة الاتصال بالخادم</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="55"/>
|
||||
<location filename="../core/errorstrings.cpp" line="56"/>
|
||||
<source>VPN connection error</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="58"/>
|
||||
<location filename="../core/errorstrings.cpp" line="59"/>
|
||||
<source>Error when retrieving configuration from API</source>
|
||||
<translation>خطأ عند استرداد التكوين من API</translation>
|
||||
</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>
|
||||
<translation>هذا التكوين بالفعل تمت إضافتة للبرنامج</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="78"/>
|
||||
<location filename="../core/errorstrings.cpp" line="80"/>
|
||||
<source>ErrorCode: %1. </source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
@@ -3378,57 +3390,67 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>التكوين لا يحتوي علي اي حاويات و اعتماد للأتصال بالخادم</translation>
|
||||
</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>
|
||||
<translation>في الاستجابة من الخادم، تم تلقي تكوين فارغ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="61"/>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<source>SSL error occurred</source>
|
||||
<translation>حدث خطأ SSL</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<location filename="../core/errorstrings.cpp" line="63"/>
|
||||
<source>Server response timeout on api request</source>
|
||||
<translation>انتهت مهلة استجابة الخادم عند طلب واجهة برمجة التطبيقات</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="63"/>
|
||||
<location filename="../core/errorstrings.cpp" line="64"/>
|
||||
<source>Missing AGW public key</source>
|
||||
<translation>مفتاح AGW عام مفقود</translation>
|
||||
</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>
|
||||
<translation>خطأ QFile: لا يمكن فتح الملف</translation>
|
||||
</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>
|
||||
<translation>خطأ QFile: ظهر خطأ اثناء القراءه من الملف</translation>
|
||||
</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>
|
||||
<translation>خطأ QFile: لا يمكن الوصول للملف</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="69"/>
|
||||
<location filename="../core/errorstrings.cpp" line="71"/>
|
||||
<source>QFile error: An unspecified error occurred</source>
|
||||
<translation>خطأ QFile: ظهر خطأ غير محدد</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="70"/>
|
||||
<location filename="../core/errorstrings.cpp" line="72"/>
|
||||
<source>QFile error: A fatal error occurred</source>
|
||||
<translation>خطأ QFile: حدث خطأ فادح</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="71"/>
|
||||
<location filename="../core/errorstrings.cpp" line="73"/>
|
||||
<source>QFile error: The operation was aborted</source>
|
||||
<translation>خطأ QFile: تم إحباط العملية</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="75"/>
|
||||
<location filename="../core/errorstrings.cpp" line="77"/>
|
||||
<source>Internal error</source>
|
||||
<translation>خطأ داخلي</translation>
|
||||
</message>
|
||||
@@ -4026,7 +4048,7 @@ While it offers a blend of security, stability, and speed, it's essential t
|
||||
<context>
|
||||
<name>VpnConnection</name>
|
||||
<message>
|
||||
<location filename="../vpnconnection.cpp" line="408"/>
|
||||
<location filename="../vpnconnection.cpp" line="409"/>
|
||||
<source>Mbps</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
@@ -4100,12 +4122,12 @@ While it offers a blend of security, stability, and speed, it's essential t
|
||||
<context>
|
||||
<name>main2</name>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="162"/>
|
||||
<location filename="../ui/qml/main2.qml" line="163"/>
|
||||
<source>Private key passphrase</source>
|
||||
<translation>عبارة المرور الخاصة بالمفتاح</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="185"/>
|
||||
<location filename="../ui/qml/main2.qml" line="186"/>
|
||||
<source>Save</source>
|
||||
<translation>احفظ</translation>
|
||||
</message>
|
||||
|
||||
@@ -88,63 +88,63 @@
|
||||
<context>
|
||||
<name>ConnectionController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="214"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="217"/>
|
||||
<source>VPN Protocols is not installed.
|
||||
Please install VPN container at first</source>
|
||||
<translation>پروتکل ویپیان نصب نشده است
|
||||
لطفا کانتینر ویپیان را نصب کنید</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="81"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="84"/>
|
||||
<source>Connecting...</source>
|
||||
<translation>در حال ارتباط...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="86"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="89"/>
|
||||
<source>Connected</source>
|
||||
<translation>متصل</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="110"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="113"/>
|
||||
<source>Preparing...</source>
|
||||
<translation>در حال آمادهسازی...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="132"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<source>Settings updated successfully, reconnnection...</source>
|
||||
<translation>تنظیمات به روز رسانی شد
|
||||
در حال اتصال دوباره...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="138"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>تنظیمات با موفقیت بهروزرسانی شدند</translation>
|
||||
</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>
|
||||
<translation>پروتکل انتخابشده در پلتفرم فعلی پشتیبانی نمیشود.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="233"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="236"/>
|
||||
<source>unable to create configuration</source>
|
||||
<translation>نمیتوان پیکربندی را ایجاد کرد.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="95"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="98"/>
|
||||
<source>Reconnecting...</source>
|
||||
<translation>اتصال دوباره...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.h" line="80"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="100"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="115"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="121"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="103"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="118"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="124"/>
|
||||
<source>Connect</source>
|
||||
<translation>اتصال</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="105"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="108"/>
|
||||
<source>Disconnecting...</source>
|
||||
<translation>قطع ارتباط...</translation>
|
||||
</message>
|
||||
@@ -258,23 +258,20 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>ImportController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="87"/>
|
||||
<source>Unable to open file</source>
|
||||
<translation>نمیتوان فایل را باز کرد.</translation>
|
||||
<translation type="vanished">نمیتوان فایل را باز کرد.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="187"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="192"/>
|
||||
<source>Invalid configuration file</source>
|
||||
<translation>فایل پیکربندی نامعتبر است.</translation>
|
||||
<translation type="vanished">فایل پیکربندی نامعتبر است.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="617"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="623"/>
|
||||
<source>Scanned %1 of %2.</source>
|
||||
<translation>ارزیابی %1 از %2.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="652"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="658"/>
|
||||
<source>In the imported configuration, potentially dangerous lines were found:</source>
|
||||
<translation>در پیکربندی وارد شده، خطوطی که ممکن است خطرناک باشند، یافت شدند:</translation>
|
||||
</message>
|
||||
@@ -282,86 +279,86 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>InstallController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="181"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="157"/>
|
||||
<source>%1 installed successfully. </source>
|
||||
<translation>%1 با موفقیت نصب شد. </translation>
|
||||
</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>
|
||||
<translation>%1 در حال حاضر بر روی سرور نصب شده است. </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="203"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="179"/>
|
||||
<source>
|
||||
Added containers that were already installed on the server</source>
|
||||
<translation>
|
||||
کانتینرهایی که بر روی سرور موجود بودند اضافه شدند</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="283"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="259"/>
|
||||
<source>
|
||||
Already installed containers were found on the server. All installed containers have been added to the application</source>
|
||||
<translation>
|
||||
کانتینرهای نصب شده بر روی سرور شناسایی شدند. تمام کانتینترهای نصب شده به نرم افزار اضافه شدند</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="541"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="517"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>تنظیمات با موفقیت بهروزرسانی شدند</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="558"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="534"/>
|
||||
<source>Server '%1' was rebooted</source>
|
||||
<translation>سرور %1 راه اندازی مجدد شد</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="570"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="546"/>
|
||||
<source>Server '%1' was removed</source>
|
||||
<translation>سرور %1 حذف شد</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="581"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="557"/>
|
||||
<source>All containers from server '%1' have been removed</source>
|
||||
<translation>تمام کانتینترها از سرور %1 حذف شدند</translation>
|
||||
</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 '%2'</source>
|
||||
<translation>%1 از سرور %2 حذف شد</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="608"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="584"/>
|
||||
<source>Api config removed</source>
|
||||
<translation>پیکربندی API حذف شد.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="630"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="606"/>
|
||||
<source>%1 cached profile cleared</source>
|
||||
<translation>%1 پروفایل ذخیره شده پاک شد.</translation>
|
||||
</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>
|
||||
<translation>لطفا به عنوان کاربر وارد شوید</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="797"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="773"/>
|
||||
<source>Server added successfully</source>
|
||||
<translation>سرور با موفقیت اضافه شد</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="845"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="821"/>
|
||||
<source>%1 installed successfully.</source>
|
||||
<translation>%1 با موفقیت نصب شد.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="877"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="855"/>
|
||||
<source>API config reloaded</source>
|
||||
<translation>پیکربندی API دوباره بارگذاری شد.</translation>
|
||||
</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>
|
||||
<translation>کشور اتصال با موفقیت به %1 تغییر یافت.</translation>
|
||||
</message>
|
||||
@@ -405,28 +402,28 @@ Already installed containers were found on the server. All installed containers
|
||||
<context>
|
||||
<name>NotificationHandler</name>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="63"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="70"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<source>AmneziaVPN</source>
|
||||
<translation>AmneziaVPN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="65"/>
|
||||
<source>VPN Connected</source>
|
||||
<translation>ویپیان وصل شد</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="72"/>
|
||||
<source>VPN Disconnected</source>
|
||||
<translation>ویپیان قطع شد</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="94"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<source>AmneziaVPN notification</source>
|
||||
<translation>اخطار AmneziaVPN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="96"/>
|
||||
<source>Unsecured network detected: </source>
|
||||
<translation>شبکه ناامن شناسایی شد: </translation>
|
||||
</message>
|
||||
@@ -2433,7 +2430,7 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation type="vanished">چی داری؟</translation>
|
||||
</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>
|
||||
<translation>فایل شامل تنظیمات اتصال</translation>
|
||||
</message>
|
||||
@@ -2442,92 +2439,102 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation type="vanished">فایل شامل تنظیمات اتصال یا بکآپ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
|
||||
<source>Connection</source>
|
||||
<translation>ارتباط</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
|
||||
<source>Settings</source>
|
||||
<translation type="unfinished">تنظیمات</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
|
||||
<source>Enable logs</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<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>
|
||||
<translation>کلید را وارد کنید، فایل پیکربندی را اضافه کنید یا کد QR را اسکن کنید</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="122"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="150"/>
|
||||
<source>Insert key</source>
|
||||
<translation>کلید را وارد کنید</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="151"/>
|
||||
<source>Insert</source>
|
||||
<translation>وارد کردن</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
|
||||
<source>Continue</source>
|
||||
<translation>ادامه دهید</translation>
|
||||
</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>
|
||||
<translation>گزینههای اتصال دیگر</translation>
|
||||
</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>
|
||||
<translation>VPN توسط Amnezia</translation>
|
||||
</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>
|
||||
<translation>اتصال به سرویسهای VPN کلاسیک پولی و رایگان از Amnezia</translation>
|
||||
</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>
|
||||
<translation>Self-hosted VPN</translation>
|
||||
</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>
|
||||
<translation>پیکربندی VPN Amnezia بر روی سرور خودتان</translation>
|
||||
</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>
|
||||
<translation>بازیابی از پشتیبان</translation>
|
||||
</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>
|
||||
<translation>باز کردن فایل پشتیبان</translation>
|
||||
</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>
|
||||
<translation>Backup files (*.backup)</translation>
|
||||
</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>
|
||||
<translation>باز کردن فایل تنظیمات</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
|
||||
<source>QR code</source>
|
||||
<translation>QR-Code</translation>
|
||||
</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>
|
||||
<translation>من هیچی ندارم</translation>
|
||||
</message>
|
||||
@@ -2544,12 +2551,12 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation>آدرس آیپی سرور (:پورت)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="116"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="113"/>
|
||||
<source>Continue</source>
|
||||
<translation>ادامه</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="173"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<source>Enter the address in the format 255.255.255.255:88</source>
|
||||
<translation>آدرس را با فرمت 255.255.255.255:88 وارد کنید</translation>
|
||||
</message>
|
||||
@@ -2564,42 +2571,42 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="78"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="75"/>
|
||||
<source>SSH Username</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="94"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="91"/>
|
||||
<source>Password or SSH private key</source>
|
||||
<translation>رمز عبور یا کلید خصوصی SSH</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="144"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="141"/>
|
||||
<source>All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>تمام دادههایی که شما وارد میکنید به شدت محرمانه است و با Amnezia یا هر شخص ثالث دیگری به اشتراک گذاشته نمیشود</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="153"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="150"/>
|
||||
<source>How to run your VPN server</source>
|
||||
<translation>چگونه سرور VPN خود را اجرا کنید</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="154"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="151"/>
|
||||
<source>Where to get connection data, step-by-step instructions for buying a VPS</source>
|
||||
<translation>دادههای اتصال را از کجا دریافت کنید و دستورالعملهای مرحله به مرحله برای خرید یک VPS</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="167"/>
|
||||
<source>Ip address cannot be empty</source>
|
||||
<translation>آدرس آیپی نمیتواند خالی باشد</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="177"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="174"/>
|
||||
<source>Login cannot be empty</source>
|
||||
<translation>نامکاربری نمیتواند خالی باشد</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="181"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="178"/>
|
||||
<source>Password/private key cannot be empty</source>
|
||||
<translation>پسورد یا کلید خصوصی نمیتواند خالی باشد</translation>
|
||||
</message>
|
||||
@@ -2939,66 +2946,71 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation>جستجو</translation>
|
||||
</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>
|
||||
<translation>تاریخ ایجاد: %1</translation>
|
||||
</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>
|
||||
<translation>آخرین ارتباط: %1</translation>
|
||||
</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>
|
||||
<translation>دادههای دریافت شده: %1</translation>
|
||||
</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>
|
||||
<translation>دادههای ارسال شده: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
|
||||
<source>Allowed IPs: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Creation date: </source>
|
||||
<translation type="vanished">تاریخ ایجاد: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="862"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
|
||||
<source>Rename</source>
|
||||
<translation>تغییر نام</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="908"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
|
||||
<source>Client name</source>
|
||||
<translation>نام کلاینت</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="921"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
|
||||
<source>Save</source>
|
||||
<translation>ذخیره</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="955"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<source>Revoke</source>
|
||||
<translation>ابطال</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="959"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
|
||||
<source>Revoke the config for a user - %1?</source>
|
||||
<translation>لغو پیکربندی برای یک کاربر - %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
|
||||
<source>The user will no longer be able to connect to your server.</source>
|
||||
<translation>کاربر دیگر نمیتواند به سرور وصل شود.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="961"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
|
||||
<source>Continue</source>
|
||||
<translation>ادامه</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="962"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
|
||||
<source>Cancel</source>
|
||||
<translation>کنسل</translation>
|
||||
</message>
|
||||
@@ -3085,17 +3097,17 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<context>
|
||||
<name>PageStart</name>
|
||||
<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>
|
||||
<translation>ثبت وقایع پس از ۱۴ روز غیرفعال شد و فایلهای ثبت وقایع حذف شدند</translation>
|
||||
</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>
|
||||
<translation>تنظیمات از فایل پشتیبان بازیابی شد</translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -3479,22 +3491,22 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation>تنظیمات شامل هیچ کانتینر یا اعتبارنامهای برای اتصال به سرور نیست</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="55"/>
|
||||
<location filename="../core/errorstrings.cpp" line="56"/>
|
||||
<source>VPN connection error</source>
|
||||
<translation>خطای اتصال VPN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="58"/>
|
||||
<location filename="../core/errorstrings.cpp" line="59"/>
|
||||
<source>Error when retrieving configuration from API</source>
|
||||
<translation>خطا هنگام بازیابی پیکربندی از API</translation>
|
||||
</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>
|
||||
<translation>این پیکربندی قبلاً به برنامه اضافه شده است</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="78"/>
|
||||
<location filename="../core/errorstrings.cpp" line="80"/>
|
||||
<source>ErrorCode: %1. </source>
|
||||
<translation>کد خطا: %1. </translation>
|
||||
</message>
|
||||
@@ -3564,57 +3576,67 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation>VPN pool error: no available addresses</translation>
|
||||
</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>
|
||||
<translation>در پاسخ از سرور، پیکربندی خالی دریافت شد</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="61"/>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<source>SSL error occurred</source>
|
||||
<translation type="unfinished">SSL error occurred</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<location filename="../core/errorstrings.cpp" line="63"/>
|
||||
<source>Server response timeout on api request</source>
|
||||
<translation>Server response timeout on api request</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="63"/>
|
||||
<location filename="../core/errorstrings.cpp" line="64"/>
|
||||
<source>Missing AGW public key</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="66"/>
|
||||
<source>QFile error: The file could not be opened</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>
|
||||
<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 accessed</source>
|
||||
<source>QFile error: The file could not be opened</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<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>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="75"/>
|
||||
<location filename="../core/errorstrings.cpp" line="77"/>
|
||||
<source>Internal error</source>
|
||||
<translation>Internal error</translation>
|
||||
</message>
|
||||
@@ -4234,7 +4256,7 @@ For more detailed information, you can
|
||||
<context>
|
||||
<name>VpnConnection</name>
|
||||
<message>
|
||||
<location filename="../vpnconnection.cpp" line="408"/>
|
||||
<location filename="../vpnconnection.cpp" line="409"/>
|
||||
<source>Mbps</source>
|
||||
<translation>Mbps</translation>
|
||||
</message>
|
||||
@@ -4316,12 +4338,12 @@ For more detailed information, you can
|
||||
<context>
|
||||
<name>main2</name>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="162"/>
|
||||
<location filename="../ui/qml/main2.qml" line="163"/>
|
||||
<source>Private key passphrase</source>
|
||||
<translation>عبارت کلید خصوصی</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="185"/>
|
||||
<location filename="../ui/qml/main2.qml" line="186"/>
|
||||
<source>Save</source>
|
||||
<translation>ذخیره</translation>
|
||||
</message>
|
||||
|
||||
@@ -89,61 +89,61 @@
|
||||
<name>ConnectionController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.h" line="80"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="100"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="115"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="121"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="103"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="118"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="124"/>
|
||||
<source>Connect</source>
|
||||
<translation>कनेक्ट</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="214"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="217"/>
|
||||
<source>VPN Protocols is not installed.
|
||||
Please install VPN container at first</source>
|
||||
<translation>पीएन प्रोटोकॉल स्थापित नहीं है.
|
||||
कृपया पहले वीपीएन कंटेनर स्थापित करें</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="86"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="89"/>
|
||||
<source>Connected</source>
|
||||
<translation>जुड़ा हुआ</translation>
|
||||
</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>
|
||||
<translation>चयनित प्रोटोकॉल वर्तमान प्लेटफ़ॉर्म पर समर्थित नहीं है</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="233"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="236"/>
|
||||
<source>unable to create configuration</source>
|
||||
<translation>कॉन्फ़िगरेशन बनाने में असमर्थ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="81"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="84"/>
|
||||
<source>Connecting...</source>
|
||||
<translation>कनेक्ट...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="95"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="98"/>
|
||||
<source>Reconnecting...</source>
|
||||
<translation>पुनः कनेक्ट हो रहा है...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="105"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="108"/>
|
||||
<source>Disconnecting...</source>
|
||||
<translation>डिस्कनेक्ट हो रहा है...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="110"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="113"/>
|
||||
<source>Preparing...</source>
|
||||
<translation>तैयार कर रहे हैं...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="132"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<source>Settings updated successfully, reconnnection...</source>
|
||||
<translation>सेटिंग्स सफलतापूर्वक अपडेट हो गईं...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="138"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>सेटिंग्स सफलतापूर्वक अपडेट हो गईं</translation>
|
||||
</message>
|
||||
@@ -254,23 +254,20 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>ImportController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="87"/>
|
||||
<source>Unable to open file</source>
|
||||
<translation>फाइल खोलने में असमर्थ</translation>
|
||||
<translation type="vanished">फाइल खोलने में असमर्थ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="187"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="192"/>
|
||||
<source>Invalid configuration file</source>
|
||||
<translation>अमान्य कॉन्फ़िगरेशन फ़ाइल</translation>
|
||||
<translation type="vanished">अमान्य कॉन्फ़िगरेशन फ़ाइल</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="617"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="623"/>
|
||||
<source>Scanned %1 of %2.</source>
|
||||
<translation>%2 में से %1 स्कैन किया गया.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="652"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="658"/>
|
||||
<source>In the imported configuration, potentially dangerous lines were found:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -278,86 +275,86 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>InstallController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="181"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="157"/>
|
||||
<source>%1 installed successfully. </source>
|
||||
<translation>%1 सफलतापूर्वक स्थापित हुआ. </translation>
|
||||
</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>
|
||||
<translation>%1 पहले से ही सर्वर पर स्थापित है. </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="203"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="179"/>
|
||||
<source>
|
||||
Added containers that were already installed on the server</source>
|
||||
<translation>
|
||||
सर्वर पर पहले से स्थापित कंटेनर जोड़े गए</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="283"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="259"/>
|
||||
<source>
|
||||
Already installed containers were found on the server. All installed containers have been added to the application</source>
|
||||
<translation>
|
||||
सर्वर पर पहले से स्थापित कंटेनर पाए गए। सभी स्थापित कंटेनरों को एप्लिकेशन में जोड़ दिया गया है</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="541"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="517"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>सेटिंग्स सफलतापूर्वक अपडेट हो गईं</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="558"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="534"/>
|
||||
<source>Server '%1' was rebooted</source>
|
||||
<translation>सर्वर '%1' रीबूट किया गया था</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="570"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="546"/>
|
||||
<source>Server '%1' was removed</source>
|
||||
<translation>सर्वर '%1' रीबूट किया गया था</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="581"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="557"/>
|
||||
<source>All containers from server '%1' have been removed</source>
|
||||
<translation>सर्वर '%1' से सभी कंटेनर हटा दिए गए हैं</translation>
|
||||
</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 '%2'</source>
|
||||
<translation>%1 को सर्वर '%2' से हटा दिया गया है</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="608"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="584"/>
|
||||
<source>Api config removed</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="630"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="606"/>
|
||||
<source>%1 cached profile cleared</source>
|
||||
<translation>%1 कैश्ड प्रोफ़ाइल साफ़ की गई</translation>
|
||||
</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>
|
||||
<translation>कृपया उपयोगकर्ता के रूप में लॉगिन करें</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="797"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="773"/>
|
||||
<source>Server added successfully</source>
|
||||
<translation>सर्वर सफलतापूर्वक जोड़ा गया</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="845"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="821"/>
|
||||
<source>%1 installed successfully.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="877"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="855"/>
|
||||
<source>API config reloaded</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -401,28 +398,28 @@ Already installed containers were found on the server. All installed containers
|
||||
<context>
|
||||
<name>NotificationHandler</name>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="63"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="70"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<source>AmneziaVPN</source>
|
||||
<translation>AmneziaVPN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="65"/>
|
||||
<source>VPN Connected</source>
|
||||
<translation>कनेक्ट</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="72"/>
|
||||
<source>VPN Disconnected</source>
|
||||
<translation>कनेक्ट</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="94"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<source>AmneziaVPN notification</source>
|
||||
<translation>AmneziaVPN अधिसूचना</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="96"/>
|
||||
<source>Unsecured network detected: </source>
|
||||
<translation>असुरक्षित नेटवर्क का पता चला: </translation>
|
||||
</message>
|
||||
@@ -2382,97 +2379,107 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation type="vanished">कनेक्शन सेटिंग्स वाली फ़ाइल</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
|
||||
<source>Connection</source>
|
||||
<translation type="unfinished">कनेक्शन</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
|
||||
<source>Settings</source>
|
||||
<translation type="unfinished">समायोजन</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
|
||||
<source>Enable logs</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/>
|
||||
<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="122"/>
|
||||
<source>Insert key</source>
|
||||
<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>
|
||||
<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>
|
||||
<translation type="unfinished">डालना</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
|
||||
<source>Continue</source>
|
||||
<translation type="unfinished">जारी रखना</translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation type="unfinished">बैकअप से बहाल करना</translation>
|
||||
</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>
|
||||
<translation type="unfinished">बैकअप फ़ाइल खोलें</translation>
|
||||
</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>
|
||||
<translation type="unfinished">बैकअप फ़ाइलें (*.backup)</translation>
|
||||
</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>
|
||||
<translation>कनेक्शन सेटिंग्स वाली फ़ाइल</translation>
|
||||
</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>
|
||||
<translation>कॉन्फ़िग फ़ाइल खोलें</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
|
||||
<source>QR code</source>
|
||||
<translation>क्यू आर संहिता</translation>
|
||||
</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>
|
||||
<translation type="unfinished">मेरे पास कुछ नहीं है</translation>
|
||||
</message>
|
||||
@@ -2494,12 +2501,12 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>सर्वर आईपी पता [:पोर्ट]</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="116"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="113"/>
|
||||
<source>Continue</source>
|
||||
<translation>जारी रखना</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="144"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="141"/>
|
||||
<source>All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>आपके द्वारा दर्ज किया गया सभी डेटा पूरी तरह से गोपनीय रहेगा और एमनेज़िया या किसी तीसरे पक्ष को साझा या प्रकट नहीं किया जाएगा</translation>
|
||||
</message>
|
||||
@@ -2509,42 +2516,42 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>255.255.255.255:22</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="78"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="75"/>
|
||||
<source>SSH Username</source>
|
||||
<translation>SSH उपयोगकर्ता नाम</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="94"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="91"/>
|
||||
<source>Password or SSH private key</source>
|
||||
<translation>पासवर्ड या SSH निजी कुंजी</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="153"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="150"/>
|
||||
<source>How to run your VPN server</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="154"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="151"/>
|
||||
<source>Where to get connection data, step-by-step instructions for buying a VPS</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="167"/>
|
||||
<source>Ip address cannot be empty</source>
|
||||
<translation>आईपी पता खाली नहीं हो सकता</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="173"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<source>Enter the address in the format 255.255.255.255:88</source>
|
||||
<translation>पता 255.255.255.255:88 प्रारूप में दर्ज करें</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="177"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="174"/>
|
||||
<source>Login cannot be empty</source>
|
||||
<translation>लॉगिन खाली नहीं हो सकता</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="181"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="178"/>
|
||||
<source>Password/private key cannot be empty</source>
|
||||
<translation>पासवर्ड/निजी कुंजी खाली नहीं हो सकती</translation>
|
||||
</message>
|
||||
@@ -2857,66 +2864,71 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>खोज</translation>
|
||||
</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>
|
||||
<translation>निर्माण दिनांक: %1</translation>
|
||||
</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>
|
||||
<translation>नवीनतम हाथ मिलाना: %1</translation>
|
||||
</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>
|
||||
<translation>प्राप्त डेटा: %1</translation>
|
||||
</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>
|
||||
<translation>डेटा भेजा गया: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
|
||||
<source>Allowed IPs: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Creation date: </source>
|
||||
<translation type="vanished">निर्माण तिथि: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="862"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
|
||||
<source>Rename</source>
|
||||
<translation>नाम बदलें</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="908"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
|
||||
<source>Client name</source>
|
||||
<translation>ग्राहक नाम</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="921"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
|
||||
<source>Save</source>
|
||||
<translation>सहेजें</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="955"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<source>Revoke</source>
|
||||
<translation>निरस्त करें</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="959"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
|
||||
<source>Revoke the config for a user - %1?</source>
|
||||
<translation>किसी उपयोक्ता के लिए कॉन्फ़िगरेशन निरस्त करें - %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
|
||||
<source>The user will no longer be able to connect to your server.</source>
|
||||
<translation>उपयोगकर्ता अब आपके सर्वर से कनेक्ट नहीं हो पाएगा.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="961"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
|
||||
<source>Continue</source>
|
||||
<translation>जारी रखना</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="962"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
|
||||
<source>Cancel</source>
|
||||
<translation>रद्द करना</translation>
|
||||
</message>
|
||||
@@ -3034,17 +3046,17 @@ Already installed containers were found on the server. All installed containers
|
||||
<context>
|
||||
<name>PageStart</name>
|
||||
<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>
|
||||
<translation>14 दिनों के बाद लॉगिंग अक्षम कर दी गई, लॉग फ़ाइलें हटा दी गईं</translation>
|
||||
</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>
|
||||
<translation type="unfinished">बैकअप फ़ाइल से सेटिंग्स पुनर्स्थापित की गईं</translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -3393,42 +3405,52 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>सर्वर से कनेक्ट होने का समय समाप्त</translation>
|
||||
</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>
|
||||
<translation>VPN कनेक्शन त्रुटि</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="58"/>
|
||||
<location filename="../core/errorstrings.cpp" line="59"/>
|
||||
<source>Error when retrieving configuration from API</source>
|
||||
<translation>एपीआई से कॉन्फ़िगरेशन पुनर्प्राप्त करते समय त्रुटि</translation>
|
||||
</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>
|
||||
<translation>यह कॉन्फ़िगरेशन पहले ही एप्लिकेशन में जोड़ा जा चुका है</translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="61"/>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<source>SSL error occurred</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<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="63"/>
|
||||
<location filename="../core/errorstrings.cpp" line="64"/>
|
||||
<source>Missing AGW public key</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation>ErrorCode: %1. </translation>
|
||||
</message>
|
||||
@@ -3493,37 +3515,37 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>कॉन्फ़िगरेशन में सर्वर से कनेक्ट करने के लिए कोई कंटेनर और क्रेडेंशियल नहीं है</translation>
|
||||
</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>
|
||||
<translation>Qफ़ाइल त्रुटि: फ़ाइल खोली नहीं जा सकी</translation>
|
||||
</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>
|
||||
<translation>Qफ़ाइल त्रुटि: फ़ाइल से पढ़ते समय एक त्रुटि उत्पन्न हुई</translation>
|
||||
</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>
|
||||
<translation>Qफ़ाइल त्रुटि: फ़ाइल तक नहीं पहुंचा जा सका</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="69"/>
|
||||
<location filename="../core/errorstrings.cpp" line="71"/>
|
||||
<source>QFile error: An unspecified error occurred</source>
|
||||
<translation>Qफ़ाइल त्रुटि: एक अनिर्दिष्ट त्रुटि उत्पन्न हुई</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="70"/>
|
||||
<location filename="../core/errorstrings.cpp" line="72"/>
|
||||
<source>QFile error: A fatal error occurred</source>
|
||||
<translation>Qफ़ाइल त्रुटि: एक घातक त्रुटि उत्पन्न हुई</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="71"/>
|
||||
<location filename="../core/errorstrings.cpp" line="73"/>
|
||||
<source>QFile error: The operation was aborted</source>
|
||||
<translation>Qफ़ाइल त्रुटि: ऑपरेशन निरस्त कर दिया गया था</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="75"/>
|
||||
<location filename="../core/errorstrings.cpp" line="77"/>
|
||||
<source>Internal error</source>
|
||||
<translation>आंतरिक त्रुटि</translation>
|
||||
</message>
|
||||
@@ -4122,7 +4144,7 @@ While it offers a blend of security, stability, and speed, it's essential t
|
||||
<context>
|
||||
<name>VpnConnection</name>
|
||||
<message>
|
||||
<location filename="../vpnconnection.cpp" line="408"/>
|
||||
<location filename="../vpnconnection.cpp" line="409"/>
|
||||
<source>Mbps</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
@@ -4208,12 +4230,12 @@ While it offers a blend of security, stability, and speed, it's essential t
|
||||
<context>
|
||||
<name>main2</name>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="162"/>
|
||||
<location filename="../ui/qml/main2.qml" line="163"/>
|
||||
<source>Private key passphrase</source>
|
||||
<translation>निजी कुंजी पासफ़्रेज़</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="185"/>
|
||||
<location filename="../ui/qml/main2.qml" line="186"/>
|
||||
<source>Save</source>
|
||||
<translation>सहेजें</translation>
|
||||
</message>
|
||||
|
||||
@@ -88,62 +88,62 @@
|
||||
<context>
|
||||
<name>ConnectionController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="214"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="217"/>
|
||||
<source>VPN Protocols is not installed.
|
||||
Please install VPN container at first</source>
|
||||
<translation>VPN ပရိုတိုကောများကို မထည့်သွင်းရသေးပါ။
|
||||
ကျေးဇူးပြု၍ VPN ကွန်တိန်နာကို အရင်ထည့်သွင်းပါ။</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="81"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="84"/>
|
||||
<source>Connecting...</source>
|
||||
<translation>ချိတ်ဆက်နေပါပြီ...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="86"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="89"/>
|
||||
<source>Connected</source>
|
||||
<translation>ချိတ်ဆက်ပြီးသွားပါပြီ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="110"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="113"/>
|
||||
<source>Preparing...</source>
|
||||
<translation>ပြင်ဆင်နေသည်...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="132"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<source>Settings updated successfully, reconnnection...</source>
|
||||
<translation>ဆက်တင်များကို အောင်မြင်စွာ အပ်ဒိတ်လုပ်ပြီးပါပြီ၊ ပြန်လည်ချိတ်ဆက်နေပါသည်...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="138"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>ဆက်တင်များကို အောင်မြင်စွာ အပ်ဒိတ်လုပ်ပြီးပါပြီ</translation>
|
||||
</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>
|
||||
<translation>ရွေးချယ်ထားသော ပရိုတိုကောကို လက်ရှိပလက်ဖောင်းပေါ်တွင် အထောက်အပံ့မပေးထားပါ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="233"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="236"/>
|
||||
<source>unable to create configuration</source>
|
||||
<translation>configuration ဖန်တီး၍မရပါ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="95"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="98"/>
|
||||
<source>Reconnecting...</source>
|
||||
<translation>ပြန်လည်ချိတ်ဆက်နေပါသည်...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.h" line="80"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="100"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="115"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="121"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="103"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="118"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="124"/>
|
||||
<source>Connect</source>
|
||||
<translation>ချိတ်ဆက်မည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="105"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="108"/>
|
||||
<source>Disconnecting...</source>
|
||||
<translation>အဆက်အသွယ်ဖြတ်နေပါသည်...</translation>
|
||||
</message>
|
||||
@@ -254,23 +254,20 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>ImportController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="87"/>
|
||||
<source>Unable to open file</source>
|
||||
<translation>ဖိုင်ကိုဖွင့်၍မရပါ</translation>
|
||||
<translation type="vanished">ဖိုင်ကိုဖွင့်၍မရပါ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="187"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="192"/>
|
||||
<source>Invalid configuration file</source>
|
||||
<translation>Configuration ဖိုင် မမှန်ကန်ပါ</translation>
|
||||
<translation type="vanished">Configuration ဖိုင် မမှန်ကန်ပါ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="617"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="623"/>
|
||||
<source>Scanned %1 of %2.</source>
|
||||
<translation>%2 ၏ %1 ကို စကင်န်ဖတ်ထားသည်.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="652"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="658"/>
|
||||
<source>In the imported configuration, potentially dangerous lines were found:</source>
|
||||
<translation>တင်သွင်းသည့် configuration တွင်၊ အန္တရာယ်ရှိနိုင်သည့်စာလိုင်းများကို တွေ့ရှိခဲ့သည်:</translation>
|
||||
</message>
|
||||
@@ -278,86 +275,86 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>InstallController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="181"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="157"/>
|
||||
<source>%1 installed successfully. </source>
|
||||
<translation>%1 ကို အောင်မြင်စွာ ထည့်သွင်းပြီးပါပြီ. </translation>
|
||||
</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>
|
||||
<translation>%1 ကို ဆာဗာတွင် ထည့်သွင်းပြီးဖြစ်သည်. </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="203"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="179"/>
|
||||
<source>
|
||||
Added containers that were already installed on the server</source>
|
||||
<translation>
|
||||
ဆာဗာတွင် ထည့်သွင်းပြီးသား ကွန်တိန်နာများကို ပေါင်းထည့်ပြီးပါပြီ။</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="283"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="259"/>
|
||||
<source>
|
||||
Already installed containers were found on the server. All installed containers have been added to the application</source>
|
||||
<translation>
|
||||
ထည့်သွင်းပြီးသား ကွန်တိန်နာများကို ဆာဗာပေါ်တွင် တွေ့ရှိခဲ့သည်။ ထည့်သွင်းထားသည့် ကွန်တိန်နာအားလုံးကို အပလီကေးရှင်းထဲသို့ ပေါင်းထည့်ပြီးပါပြီ။</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="541"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="517"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>ဆက်တင်များကို အောင်မြင်စွာ အပ်ဒိတ်လုပ်ပြီးပါပြီ။</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="558"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="534"/>
|
||||
<source>Server '%1' was rebooted</source>
|
||||
<translation>ဆာဗာ '%1' ကို ပြန်လည်စတင်ခဲ့သည်။</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="570"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="546"/>
|
||||
<source>Server '%1' was removed</source>
|
||||
<translation>ဆာဗာ '%1' ကို ဖယ်ရှားခဲ့သည်။</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="581"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="557"/>
|
||||
<source>All containers from server '%1' have been removed</source>
|
||||
<translation>ဆာဗာ '%1' မှ ကွန်တိန်နာအားလုံးကို ဖယ်ရှားလိုက်ပါပြီ။</translation>
|
||||
</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 '%2'</source>
|
||||
<translation>%1 ကို ဆာဗာ '%2' မှ ဖယ်ရှားလိုက်ပါပြီ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="608"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="584"/>
|
||||
<source>Api config removed</source>
|
||||
<translation>Api config ကိုဖယ်ရှားလိုက်သည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="630"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="606"/>
|
||||
<source>%1 cached profile cleared</source>
|
||||
<translation>ကက်ရှ်လုပ်ထားတဲ့ ပရိုဖိုင် %1 ခုကို ရှင်းပြီးပါပြီ</translation>
|
||||
</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>
|
||||
<translation>အသုံးပြုသူအဖြစ် log in ဝင်ရောက်ပါ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="797"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="773"/>
|
||||
<source>Server added successfully</source>
|
||||
<translation>ဆာဗာကို အောင်မြင်စွာ ထည့်သွင်းပြီးပါပြီ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="845"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="821"/>
|
||||
<source>%1 installed successfully.</source>
|
||||
<translation>%1 ခုကို အောင်မြင်စွာ ထည့်သွင်းပြီးပါပြီ.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="877"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="855"/>
|
||||
<source>API config reloaded</source>
|
||||
<translation>API config ကို ပြန်လည်စတင်လိုက်ပါပြီ</translation>
|
||||
</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>
|
||||
<translation>ချိတ်ဆက်မှုနိုင်ငံကို %1 သို့ အောင်မြင်စွာ ပြောင်းလဲလိုက်ပါပြီ</translation>
|
||||
</message>
|
||||
@@ -401,28 +398,28 @@ Already installed containers were found on the server. All installed containers
|
||||
<context>
|
||||
<name>NotificationHandler</name>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="63"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="70"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<source>AmneziaVPN</source>
|
||||
<translation>AmneziaVPN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="65"/>
|
||||
<source>VPN Connected</source>
|
||||
<translation>VPN ချိတ်ဆက်ထားပါပြီ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="72"/>
|
||||
<source>VPN Disconnected</source>
|
||||
<translation>VPN ဖြုတ်လိုက်ပါပြီ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="94"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<source>AmneziaVPN notification</source>
|
||||
<translation>AmneziaVPN နိုတီ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="96"/>
|
||||
<source>Unsecured network detected: </source>
|
||||
<translation>လုံခြုံမှုမရှိသောကွန်ရက်မှန်း ထောက်လှန်းမိသည်: </translation>
|
||||
</message>
|
||||
@@ -2327,97 +2324,107 @@ Already installed containers were found on the server. All installed containers
|
||||
<context>
|
||||
<name>PageSetupWizardConfigSource</name>
|
||||
<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>
|
||||
<translation>ချိတ်ဆက်မှုဆက်တင်များပါဝင်သောဖိုင်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
|
||||
<source>Connection</source>
|
||||
<translation>ချိတ်ဆက်မှု</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
|
||||
<source>Settings</source>
|
||||
<translation type="unfinished">ဆက်တင်များ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
|
||||
<source>Enable logs</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<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>
|
||||
<translation>Key ကိုထည့်မည်၊ ဖွဲ့စည်းမှုဖိုင်တစ်ခုကိုထည့်မည် သို့မဟုတ် QR-ကုဒ်ကို စကင်န်ဖတ်မည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="122"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="150"/>
|
||||
<source>Insert key</source>
|
||||
<translation>Key ကိုထည့်သွင်းမည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="151"/>
|
||||
<source>Insert</source>
|
||||
<translation>ထည့်သွင်းမည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
|
||||
<source>Continue</source>
|
||||
<translation>ဆက်လက်လုပ်ဆောင်မည်</translation>
|
||||
</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>
|
||||
<translation>အခြားချိတ်ဆက်မှုရွေးချယ်စရာများ</translation>
|
||||
</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>
|
||||
<translation>Amnezia မှ VPN</translation>
|
||||
</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>
|
||||
<translation>Amnezia မှ အခပေးနှင့် အခမဲ့ မူလ VPN ဝန်ဆောင်မှုများသို့ ချိတ်ဆက်မည်</translation>
|
||||
</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>
|
||||
<translation>ကိုယ်တိုင် host လုပ်ထားသော VPN</translation>
|
||||
</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>
|
||||
<translation>Amnezia VPN ကို သင်၏ကိုယ်ပိုင်ဆာဗာပေါ်တွင် စီစဥ်ချိန်ညှိမည်</translation>
|
||||
</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>
|
||||
<translation>အရံဖိုင်မှ ပြန်လည်ရယူမည်</translation>
|
||||
</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>
|
||||
<translation>အရံဖိုင်ကို ဖွင့်မည်</translation>
|
||||
</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>
|
||||
<translation>အရံဖိုင်များ (*.backup)</translation>
|
||||
</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>
|
||||
<translation>config ဖိုင်ကိုဖွင့်မည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
|
||||
<source>QR code</source>
|
||||
<translation>QR-ကုဒ်</translation>
|
||||
</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>
|
||||
<translation>ကျွန်ုပ်တွင်ဘာမှမရှိပါ</translation>
|
||||
</message>
|
||||
@@ -2430,12 +2437,12 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>ဆာဗာ IP လိပ်စာ [:port]</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="116"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="113"/>
|
||||
<source>Continue</source>
|
||||
<translation>ဆက်လက်လုပ်ဆောင်မည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="173"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<source>Enter the address in the format 255.255.255.255:88</source>
|
||||
<translation>လိပ်စာကို 255.255.255.255:88 ဖော်မတ်ဖြင့် ထည့်ပါ</translation>
|
||||
</message>
|
||||
@@ -2450,42 +2457,42 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>255.255.255.255:22</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="78"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="75"/>
|
||||
<source>SSH Username</source>
|
||||
<translation>SSH အသုံးပြုသူအမည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="94"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="91"/>
|
||||
<source>Password or SSH private key</source>
|
||||
<translation>စကားဝှက် သိုမဟုတ် SSH private key</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="144"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="141"/>
|
||||
<source>All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>သင်ထည့်သွင်းသည့်ဒေတာအားလုံးကို တင်းကြပ်လုံခြုံစွာလျှို့ဝှက်ထားမည်ဖြစ်ပြီး Amnezia သို့မဟုတ် မည်သည့်ပြင်ပအဖွဲ့အစည်းကိုမျှ မျှဝေမည် သို့မဟုတ် ထုတ်ဖော်မည်မဟုတ်ပါ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="153"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="150"/>
|
||||
<source>How to run your VPN server</source>
|
||||
<translation>သင်၏ဆာဗာကို လည်ပတ်ပုံလည်ပတ်နည်း</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="154"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="151"/>
|
||||
<source>Where to get connection data, step-by-step instructions for buying a VPS</source>
|
||||
<translation>ချိတ်ဆက်မှုဒေတာကို ဘယ်မှာရနိုင်မလဲ၊ VPS ဝယ်ယူပုံဝယ်ယူနည်းအတွက် အဆင့်ဆင့် ညွှန်ကြားချက်များ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="167"/>
|
||||
<source>Ip address cannot be empty</source>
|
||||
<translation>IP လိပ်စာသည် ဗလာမဖြစ်ရပါ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="177"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="174"/>
|
||||
<source>Login cannot be empty</source>
|
||||
<translation>လော့ဂ်အင်အချက်အလက်သည် ဗလာမဖြစ်ရပါ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="181"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="178"/>
|
||||
<source>Password/private key cannot be empty</source>
|
||||
<translation>စကားဝှက်/private key သည် ဗလာမဖြစ်ရပါ</translation>
|
||||
</message>
|
||||
@@ -2805,62 +2812,67 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>ရှာဖွေမည်</translation>
|
||||
</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>
|
||||
<translation>ဖန်တီးပြုလုပ်သည့်ရက်စွဲ: %1</translation>
|
||||
</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>
|
||||
<translation>နောက်ဆုံး handshake လုပ်ခြင်း: %1</translation>
|
||||
</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>
|
||||
<translation>လက်ခံရရှိသည့်ဒေတာ: %1</translation>
|
||||
</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>
|
||||
<translation>ပေးပို့လိုက်သည့်ဒေတာ: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="862"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
|
||||
<source>Allowed IPs: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
|
||||
<source>Rename</source>
|
||||
<translation>အမည်ပြောင်းမည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="908"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
|
||||
<source>Client name</source>
|
||||
<translation>ကလိုင်းရင့်အမည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="921"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
|
||||
<source>Save</source>
|
||||
<translation>သိမ်းဆည်းမည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="955"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<source>Revoke</source>
|
||||
<translation>ပြန်ရုပ်သိမ်းမည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="959"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
|
||||
<source>Revoke the config for a user - %1?</source>
|
||||
<translation>အသုံးပြုသူ %1 အတွက် config ကို ပြန်လည်ရုပ်သိမ်းမည်လား?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
|
||||
<source>The user will no longer be able to connect to your server.</source>
|
||||
<translation>ဤအသုံးပြုသူသည် သင့်ဆာဗာသို့ ချိတ်ဆက်နိုင်တော့မည်မဟုတ်ပါ.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="961"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
|
||||
<source>Continue</source>
|
||||
<translation>ဆက်လက်လုပ်ဆောင်မည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="962"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
|
||||
<source>Cancel</source>
|
||||
<translation>ပယ်ဖျက်မည်</translation>
|
||||
</message>
|
||||
@@ -2947,17 +2959,17 @@ Already installed containers were found on the server. All installed containers
|
||||
<context>
|
||||
<name>PageStart</name>
|
||||
<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>
|
||||
<translation>၁၄ ရက်အကြာတွင် Logging ကို ပိတ်ခဲ့သည်၊ မှတ်တမ်းဖိုင်များကို ဖျက်ပစ်လိုက်ပြီဖြစ်သည်</translation>
|
||||
</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>
|
||||
<translation>ဆက်တင်များကို အရံဖိုင်မှ ပြန်လည်ရယူပြီးပါပြီ</translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -3289,17 +3301,17 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>Config တွင် ဆာဗာသို့ချိတ်ဆက်ရန်အတွက် ကွန်တိန်နာများနှင့် အထောက်အထားများ မပါဝင်ပါ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="58"/>
|
||||
<location filename="../core/errorstrings.cpp" line="59"/>
|
||||
<source>Error when retrieving configuration from API</source>
|
||||
<translation>API မှ စီစဉ်သတ်မှတ်မှုကို ရယူသည့်အခါ အမှားအယွင်းဖြစ်ပေါ်နေသည်</translation>
|
||||
</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>
|
||||
<translation>ဤ config ကို အပလီကေးရှင်းထဲသို့ ထည့်သွင်းပြီးဖြစ်သည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="78"/>
|
||||
<location filename="../core/errorstrings.cpp" line="80"/>
|
||||
<source>ErrorCode: %1. </source>
|
||||
<translation>မှားယွင်းမှုကုတ်: %1. </translation>
|
||||
</message>
|
||||
@@ -3369,62 +3381,72 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>VPN pool မှားယွင်းမှု: ရရှိနိုင်သောလိပ်စာများမရှိပါ</translation>
|
||||
</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>
|
||||
<translation>VPN ချိတ်ဆက်မှုမှားယွင်းနေပါသည်</translation>
|
||||
</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>
|
||||
<translation>ဆာဗာမှ တုံ့ပြန်မှုတွင်၊ config အလွတ်တစ်ခုကို လက်ခံရရှိခဲ့သည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="61"/>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<source>SSL error occurred</source>
|
||||
<translation>SSL မှားယွင်းမှုဖြစ်သွားသည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<location filename="../core/errorstrings.cpp" line="63"/>
|
||||
<source>Server response timeout on api request</source>
|
||||
<translation>Api တောင်းဆိုမှုတွင် ဆာဗာတုံ့ပြန်မှု အချိန်ကုန်သွားသည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="63"/>
|
||||
<location filename="../core/errorstrings.cpp" line="64"/>
|
||||
<source>Missing AGW public key</source>
|
||||
<translation>AGW public key ပျောက်ဆုံးနေသည်</translation>
|
||||
</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>
|
||||
<translation>QFile မှားယွင်းမှု: ဖိုင်ကို ဖွင့်၍မရပါ</translation>
|
||||
</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>
|
||||
<translation>QFile မှားယွင်းမှု: ဖိုင်ကိုဖတ်နေစဥ်အတွင်း မှားယွင်းမှုဖြစ်သွားသည်</translation>
|
||||
</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>
|
||||
<translation>QFile မှားယွင်းမှု: ဖိုင်ကို ဝင်၍မရပါ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="69"/>
|
||||
<location filename="../core/errorstrings.cpp" line="71"/>
|
||||
<source>QFile error: An unspecified error occurred</source>
|
||||
<translation>QFile မှားယွင်းမှု: သတ်မှတ်မထားသော မှားယွင်းမှုတစ်ခု ဖြစ်ပွားခဲ့သည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="70"/>
|
||||
<location filename="../core/errorstrings.cpp" line="72"/>
|
||||
<source>QFile error: A fatal error occurred</source>
|
||||
<translation>QFile မှားယွင်းမှု: ကြီးမားသော မှားယွင်းမှုတစ်ခု ဖြစ်ပွားခဲ့သည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="71"/>
|
||||
<location filename="../core/errorstrings.cpp" line="73"/>
|
||||
<source>QFile error: The operation was aborted</source>
|
||||
<translation>QFile မှားယွင်းမှု: လုပ်ငန်းစဥ်ကို ဖျက်သိမ်းလိုက်ရသည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="75"/>
|
||||
<location filename="../core/errorstrings.cpp" line="77"/>
|
||||
<source>Internal error</source>
|
||||
<translation>စက်တွင်းဖြစ်သော မှားယွင်းမှု</translation>
|
||||
</message>
|
||||
@@ -4031,7 +4053,7 @@ For more detailed information, you can
|
||||
<context>
|
||||
<name>VpnConnection</name>
|
||||
<message>
|
||||
<location filename="../vpnconnection.cpp" line="408"/>
|
||||
<location filename="../vpnconnection.cpp" line="409"/>
|
||||
<source>Mbps</source>
|
||||
<translation>Mbps</translation>
|
||||
</message>
|
||||
@@ -4105,12 +4127,12 @@ For more detailed information, you can
|
||||
<context>
|
||||
<name>main2</name>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="162"/>
|
||||
<location filename="../ui/qml/main2.qml" line="163"/>
|
||||
<source>Private key passphrase</source>
|
||||
<translation>ကိုယ်ပိုင် key စကားဝှက်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="185"/>
|
||||
<location filename="../ui/qml/main2.qml" line="186"/>
|
||||
<source>Save</source>
|
||||
<translation>သိမ်းဆည်းမည်</translation>
|
||||
</message>
|
||||
|
||||
@@ -88,62 +88,62 @@
|
||||
<context>
|
||||
<name>ConnectionController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="214"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="217"/>
|
||||
<source>VPN Protocols is not installed.
|
||||
Please install VPN container at first</source>
|
||||
<translation>VPN-протоколы не установлены.
|
||||
Пожалуйста, установите протокол</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="81"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="84"/>
|
||||
<source>Connecting...</source>
|
||||
<translation>Подключение...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="86"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="89"/>
|
||||
<source>Connected</source>
|
||||
<translation>Подключено</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="110"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="113"/>
|
||||
<source>Preparing...</source>
|
||||
<translation>Подготовка...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="132"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<source>Settings updated successfully, reconnnection...</source>
|
||||
<translation>Настройки успешно обновлены, переподключение...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="138"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>Настройки успешно обновлены</translation>
|
||||
</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>
|
||||
<translation>Выбранный протокол не поддерживается на данном устройстве</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="233"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="236"/>
|
||||
<source>unable to create configuration</source>
|
||||
<translation>не удалось создать конфигурацию</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="95"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="98"/>
|
||||
<source>Reconnecting...</source>
|
||||
<translation>Переподключение...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.h" line="80"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="100"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="115"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="121"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="103"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="118"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="124"/>
|
||||
<source>Connect</source>
|
||||
<translation>Подключиться</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="105"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="108"/>
|
||||
<source>Disconnecting...</source>
|
||||
<translation>Отключение...</translation>
|
||||
</message>
|
||||
@@ -258,23 +258,20 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>ImportController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="87"/>
|
||||
<source>Unable to open file</source>
|
||||
<translation>Невозможно открыть файл</translation>
|
||||
<translation type="vanished">Невозможно открыть файл</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="187"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="192"/>
|
||||
<source>Invalid configuration file</source>
|
||||
<translation>Неверный файл конфигурации</translation>
|
||||
<translation type="vanished">Неверный файл конфигурации</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="617"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="623"/>
|
||||
<source>Scanned %1 of %2.</source>
|
||||
<translation>Отсканировано %1 из %2.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="652"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="658"/>
|
||||
<source>In the imported configuration, potentially dangerous lines were found:</source>
|
||||
<translation>В импортированной конфигурации были обнаружены потенциально опасные строки:</translation>
|
||||
</message>
|
||||
@@ -282,86 +279,86 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>InstallController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="181"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="157"/>
|
||||
<source>%1 installed successfully. </source>
|
||||
<translation>%1 успешно установлен. </translation>
|
||||
</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>
|
||||
<translation>%1 уже установлен на сервер. </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="203"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="179"/>
|
||||
<source>
|
||||
Added containers that were already installed on the server</source>
|
||||
<translation>
|
||||
Добавлены сервисы и протоколы, которые были ранее установлены на сервер</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="283"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="259"/>
|
||||
<source>
|
||||
Already installed containers were found on the server. All installed containers have been added to the application</source>
|
||||
<translation>
|
||||
На сервере обнаружены установленные протоколы и сервисы. Все они были добавлены в приложение</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="541"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="517"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>Настройки успешно обновлены</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="558"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="534"/>
|
||||
<source>Server '%1' was rebooted</source>
|
||||
<translation>Сервер '%1' был перезагружен</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="570"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="546"/>
|
||||
<source>Server '%1' was removed</source>
|
||||
<translation>Сервер '%1' был удален</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="581"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="557"/>
|
||||
<source>All containers from server '%1' have been removed</source>
|
||||
<translation>Все протоколы и сервисы были удалены с сервера '%1'</translation>
|
||||
</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 '%2'</source>
|
||||
<translation>%1 был удален с сервера '%2'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="608"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="584"/>
|
||||
<source>Api config removed</source>
|
||||
<translation>Конфигурация API удалена</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="630"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="606"/>
|
||||
<source>%1 cached profile cleared</source>
|
||||
<translation>%1 закэшированный профиль очищен</translation>
|
||||
</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>
|
||||
<translation>Пожалуйста, войдите в систему от имени пользователя</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="797"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="773"/>
|
||||
<source>Server added successfully</source>
|
||||
<translation>Сервер успешно добавлен</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="845"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="821"/>
|
||||
<source>%1 installed successfully.</source>
|
||||
<translation>%1 успешно установлен.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="877"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="855"/>
|
||||
<source>API config reloaded</source>
|
||||
<translation>Конфигурация API перезагружена</translation>
|
||||
</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>
|
||||
<translation>Изменение страны подключения на %1</translation>
|
||||
</message>
|
||||
@@ -405,28 +402,28 @@ Already installed containers were found on the server. All installed containers
|
||||
<context>
|
||||
<name>NotificationHandler</name>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="63"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="70"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<source>AmneziaVPN</source>
|
||||
<translation>AmneziaVPN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="65"/>
|
||||
<source>VPN Connected</source>
|
||||
<translation>VPN подключен</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="72"/>
|
||||
<source>VPN Disconnected</source>
|
||||
<translation>VPN выключен</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="94"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<source>AmneziaVPN notification</source>
|
||||
<translation>Уведомление AmneziaVPN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="96"/>
|
||||
<source>Unsecured network detected: </source>
|
||||
<translation>Обнаружена незащищенная сеть: </translation>
|
||||
</message>
|
||||
@@ -2505,7 +2502,7 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation type="vanished">Что у вас есть?</translation>
|
||||
</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>
|
||||
<translation>Файл с настройками подключения</translation>
|
||||
</message>
|
||||
@@ -2514,92 +2511,102 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation type="vanished">Файл с настройками подключения или резервной копией</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
|
||||
<source>Connection</source>
|
||||
<translation>Соединение</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
|
||||
<source>Settings</source>
|
||||
<translation type="unfinished">Настройки</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
|
||||
<source>Enable logs</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<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>
|
||||
<translation>Вставьте ключ, добавьте файл конфигурации или отсканируйте QR-код</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="122"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="150"/>
|
||||
<source>Insert key</source>
|
||||
<translation>Вставьте ключ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="151"/>
|
||||
<source>Insert</source>
|
||||
<translation>Вставить</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
|
||||
<source>Continue</source>
|
||||
<translation>Продолжить</translation>
|
||||
</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>
|
||||
<translation>Другие варианты подключения</translation>
|
||||
</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>
|
||||
<translation>VPN от Amnezia</translation>
|
||||
</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>
|
||||
<translation>Подключайтесь к классическим платным и бесплатным VPN-сервисам от Amnezia</translation>
|
||||
</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>
|
||||
<translation>Self-hosted VPN</translation>
|
||||
</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>
|
||||
<translation>Настроить VPN на собственном сервере</translation>
|
||||
</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>
|
||||
<translation>Восстановить из резервной копии</translation>
|
||||
</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>
|
||||
<translation>Открыть резервную копию</translation>
|
||||
</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>
|
||||
<translation>Файлы резервных копий (*.backup)</translation>
|
||||
</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>
|
||||
<translation>Открыть файл с конфигурацией</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
|
||||
<source>QR code</source>
|
||||
<translation>QR-код</translation>
|
||||
</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>
|
||||
<translation>У меня ничего нет</translation>
|
||||
</message>
|
||||
@@ -2628,7 +2635,7 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation type="vanished">Password / SSH private key</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="116"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="113"/>
|
||||
<source>Continue</source>
|
||||
<translation>Продолжить</translation>
|
||||
</message>
|
||||
@@ -2638,7 +2645,7 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation type="vanished">Все данные, которые вы вводите, останутся строго конфиденциальными и не будут переданы или раскрыты Amnezia или каким-либо третьим лицам</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="173"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<source>Enter the address in the format 255.255.255.255:88</source>
|
||||
<translation>Введите адрес в формате 255.255.255.255:88</translation>
|
||||
</message>
|
||||
@@ -2657,42 +2664,42 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>255.255.255.255:22</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="78"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="75"/>
|
||||
<source>SSH Username</source>
|
||||
<translation>Имя пользователя SSH</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="94"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="91"/>
|
||||
<source>Password or SSH private key</source>
|
||||
<translation>Пароль или закрытый ключ SSH</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="144"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="141"/>
|
||||
<source>All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>Все данные, которые вы вводите, останутся строго конфиденциальными и не будут переданы или раскрыты Amnezia или каким-либо третьим лицам</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="153"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="150"/>
|
||||
<source>How to run your VPN server</source>
|
||||
<translation>Как создать VPN на собственном сервере</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="154"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="151"/>
|
||||
<source>Where to get connection data, step-by-step instructions for buying a VPS</source>
|
||||
<translation>Где взять данные для подключения, пошаговые инстуркции по покупке VPS</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="167"/>
|
||||
<source>Ip address cannot be empty</source>
|
||||
<translation>Поле с IP-адресом не может быть пустым</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="177"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="174"/>
|
||||
<source>Login cannot be empty</source>
|
||||
<translation>Поле с логином не может быть пустым</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="181"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="178"/>
|
||||
<source>Password/private key cannot be empty</source>
|
||||
<translation>Поле с паролем/закрытым ключом не может быть пустым</translation>
|
||||
</message>
|
||||
@@ -3068,66 +3075,71 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>Поиск</translation>
|
||||
</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>
|
||||
<translation>Дата создания: %1</translation>
|
||||
</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>
|
||||
<translation>Последнее рукопожатие: %1</translation>
|
||||
</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>
|
||||
<translation>Получено данных: %1</translation>
|
||||
</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>
|
||||
<translation>Отправлено данных: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
|
||||
<source>Allowed IPs: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Creation date: </source>
|
||||
<translation type="vanished">Дата создания: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="862"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
|
||||
<source>Rename</source>
|
||||
<translation>Переименовать</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="908"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
|
||||
<source>Client name</source>
|
||||
<translation>Имя клиента</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="921"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
|
||||
<source>Save</source>
|
||||
<translation>Сохранить</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="955"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<source>Revoke</source>
|
||||
<translation>Отозвать</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="959"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
|
||||
<source>Revoke the config for a user - %1?</source>
|
||||
<translation>Отозвать конфигурацию для пользователя - %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
|
||||
<source>The user will no longer be able to connect to your server.</source>
|
||||
<translation>Пользователь больше не сможет подключаться к вашему серверу.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="961"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
|
||||
<source>Continue</source>
|
||||
<translation>Продолжить</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="962"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
|
||||
<source>Cancel</source>
|
||||
<translation>Отменить</translation>
|
||||
</message>
|
||||
@@ -3218,17 +3230,17 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<context>
|
||||
<name>PageStart</name>
|
||||
<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>
|
||||
<translation>Логирование было отключено по прошествии 14 дней, файлы логов были удалены.</translation>
|
||||
</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>
|
||||
<translation>Настройки восстановлены из бэкап файла</translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -3625,17 +3637,17 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>Конфигурация не содержит каких-либо контейнеров и учетных данных для подключения к серверу</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="58"/>
|
||||
<location filename="../core/errorstrings.cpp" line="59"/>
|
||||
<source>Error when retrieving configuration from API</source>
|
||||
<translation>Ошибка при получении конфигурации из API</translation>
|
||||
</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>
|
||||
<translation>Данная конфигурация уже была добавлена в приложение</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="78"/>
|
||||
<location filename="../core/errorstrings.cpp" line="80"/>
|
||||
<source>ErrorCode: %1. </source>
|
||||
<translation>Код ошибки: %1. </translation>
|
||||
</message>
|
||||
@@ -3694,62 +3706,72 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>Ошибка пула VPN: нет доступных адресов</translation>
|
||||
</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>
|
||||
<translation>Ошибка VPN-соединения</translation>
|
||||
</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>
|
||||
<translation>В ответе от сервера была получена пустая конфигурация</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="61"/>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<source>SSL error occurred</source>
|
||||
<translation>Произошла ошибка SSL</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<location filename="../core/errorstrings.cpp" line="63"/>
|
||||
<source>Server response timeout on api request</source>
|
||||
<translation>Тайм-аут ответа сервера на запрос API</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="63"/>
|
||||
<location filename="../core/errorstrings.cpp" line="64"/>
|
||||
<source>Missing AGW public key</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation>Ошибка QFile: не удалось открыть файл</translation>
|
||||
</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>
|
||||
<translation>Ошибка QFile: произошла ошибка при чтении из файла</translation>
|
||||
</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>
|
||||
<translation>Ошибка QFile: не удалось получить доступ к файлу</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="69"/>
|
||||
<location filename="../core/errorstrings.cpp" line="71"/>
|
||||
<source>QFile error: An unspecified error occurred</source>
|
||||
<translation>Ошибка QFile: произошла неизвестная ошибка</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="70"/>
|
||||
<location filename="../core/errorstrings.cpp" line="72"/>
|
||||
<source>QFile error: A fatal error occurred</source>
|
||||
<translation>Ошибка QFile: произошла фатальная ошибка</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="71"/>
|
||||
<location filename="../core/errorstrings.cpp" line="73"/>
|
||||
<source>QFile error: The operation was aborted</source>
|
||||
<translation>Ошибка QFile: операция была прервана</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="75"/>
|
||||
<location filename="../core/errorstrings.cpp" line="77"/>
|
||||
<source>Internal error</source>
|
||||
<translation>Внутренняя ошибка</translation>
|
||||
</message>
|
||||
@@ -4449,7 +4471,7 @@ This means that AmneziaWG keeps the fast performance of the original while addin
|
||||
<context>
|
||||
<name>VpnConnection</name>
|
||||
<message>
|
||||
<location filename="../vpnconnection.cpp" line="408"/>
|
||||
<location filename="../vpnconnection.cpp" line="409"/>
|
||||
<source>Mbps</source>
|
||||
<translation>Мбит/с</translation>
|
||||
</message>
|
||||
@@ -4547,12 +4569,12 @@ This means that AmneziaWG keeps the fast performance of the original while addin
|
||||
<context>
|
||||
<name>main2</name>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="162"/>
|
||||
<location filename="../ui/qml/main2.qml" line="163"/>
|
||||
<source>Private key passphrase</source>
|
||||
<translation>Парольная фраза для закрытого ключа</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="185"/>
|
||||
<location filename="../ui/qml/main2.qml" line="186"/>
|
||||
<source>Save</source>
|
||||
<translation>Сохранить</translation>
|
||||
</message>
|
||||
|
||||
@@ -111,62 +111,62 @@
|
||||
<context>
|
||||
<name>ConnectionController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="214"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="217"/>
|
||||
<source>VPN Protocols is not installed.
|
||||
Please install VPN container at first</source>
|
||||
<translation>VPN протоколи не встановлено.
|
||||
Будь-ласка, встановіть VPN контейнер</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="233"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="236"/>
|
||||
<source>unable to create configuration</source>
|
||||
<translation>Неможливо створити конфігурацію</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="81"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="84"/>
|
||||
<source>Connecting...</source>
|
||||
<translation>Підключення...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="86"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="89"/>
|
||||
<source>Connected</source>
|
||||
<translation>Підключено</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="110"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="113"/>
|
||||
<source>Preparing...</source>
|
||||
<translation>Підготовка...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="132"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<source>Settings updated successfully, reconnnection...</source>
|
||||
<translation>Налаштування оновлено, підключення...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="138"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>Налаштування оновлено</translation>
|
||||
</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>
|
||||
<translation>Вибраний протокол не підтримується на цьому пристрої</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="95"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="98"/>
|
||||
<source>Reconnecting...</source>
|
||||
<translation>Перепідключення...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.h" line="80"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="100"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="115"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="121"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="103"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="118"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="124"/>
|
||||
<source>Connect</source>
|
||||
<translation>Підключитись</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="105"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="108"/>
|
||||
<source>Disconnecting...</source>
|
||||
<translation>Відключаємось...</translation>
|
||||
</message>
|
||||
@@ -285,23 +285,20 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>ImportController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="87"/>
|
||||
<source>Unable to open file</source>
|
||||
<translation>Неможливо відкрити файл</translation>
|
||||
<translation type="vanished">Неможливо відкрити файл</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="187"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="192"/>
|
||||
<source>Invalid configuration file</source>
|
||||
<translation>Недійсний файл конфігурації</translation>
|
||||
<translation type="vanished">Недійсний файл конфігурації</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="617"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="623"/>
|
||||
<source>Scanned %1 of %2.</source>
|
||||
<translation>Відскановано %1 з %2.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="652"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="658"/>
|
||||
<source>In the imported configuration, potentially dangerous lines were found:</source>
|
||||
<translation>У імпортованій конфігурації знайдено потенційно небезпечні рядки:</translation>
|
||||
</message>
|
||||
@@ -309,85 +306,85 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>InstallController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="181"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="157"/>
|
||||
<source>%1 installed successfully. </source>
|
||||
<translation>%1 встановлено. </translation>
|
||||
</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>
|
||||
<translation>%1 вже встановлено на сервері. </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="203"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="179"/>
|
||||
<source>
|
||||
Added containers that were already installed on the server</source>
|
||||
<translation>Додані сервіси і протоколи, які були раніше встановлені на сервері</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="283"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="259"/>
|
||||
<source>
|
||||
Already installed containers were found on the server. All installed containers have been added to the application</source>
|
||||
<translation>
|
||||
На сервері знайдені сервіси та протоколи, всі вони додані в застосунок</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="541"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="517"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>Налаштування оновлено</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="558"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="534"/>
|
||||
<source>Server '%1' was rebooted</source>
|
||||
<translation>Сервер '%1' перезавантажено</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="570"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="546"/>
|
||||
<source>Server '%1' was removed</source>
|
||||
<translation>Сервер '%1' був видалений</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="581"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="557"/>
|
||||
<source>All containers from server '%1' have been removed</source>
|
||||
<translation>Всі сервіси та протоколи були видалені з сервера '%1'</translation>
|
||||
</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 '%2'</source>
|
||||
<translation>%1 був видалений з сервера '%2'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="608"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="584"/>
|
||||
<source>Api config removed</source>
|
||||
<translation>Конфігурацію API видалено</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="630"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="606"/>
|
||||
<source>%1 cached profile cleared</source>
|
||||
<translation>Кешований профіль %1 очищено</translation>
|
||||
</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>
|
||||
<translation>Буль-ласка, увійдіть в систему від імені користувача</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="797"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="773"/>
|
||||
<source>Server added successfully</source>
|
||||
<translation>Сервер додано</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="845"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="821"/>
|
||||
<source>%1 installed successfully.</source>
|
||||
<translation>%1 встановлено успішно.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="877"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="855"/>
|
||||
<source>API config reloaded</source>
|
||||
<translation>Конфігурацію API перезавантажено</translation>
|
||||
</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>
|
||||
<translation>Успішно змінено країну підключення на %1</translation>
|
||||
</message>
|
||||
@@ -431,28 +428,28 @@ Already installed containers were found on the server. All installed containers
|
||||
<context>
|
||||
<name>NotificationHandler</name>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="63"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="70"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<source>AmneziaVPN</source>
|
||||
<translation>AmneziaVPN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="65"/>
|
||||
<source>VPN Connected</source>
|
||||
<translation>VPN Підключено</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="72"/>
|
||||
<source>VPN Disconnected</source>
|
||||
<translation>VPN Вимкнено</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="94"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<source>AmneziaVPN notification</source>
|
||||
<translation>Сповіщення AmneziaVPN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="96"/>
|
||||
<source>Unsecured network detected: </source>
|
||||
<translation>Знайдена не захищена мережа: </translation>
|
||||
</message>
|
||||
@@ -2591,7 +2588,7 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation type="vanished">Виберіть що у вас є</translation>
|
||||
</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>
|
||||
<translation>Файл з налаштуваннями підключення</translation>
|
||||
</message>
|
||||
@@ -2600,92 +2597,102 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation type="vanished">Файл з налаштуваннями підключення або бекап</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
|
||||
<source>Connection</source>
|
||||
<translation>Підключення</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
|
||||
<source>Settings</source>
|
||||
<translation type="unfinished">Налаштування</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
|
||||
<source>Enable logs</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<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>
|
||||
<translation>Вставте ключ, додайте файл конфігурації або відскануйте QR-код</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="122"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="150"/>
|
||||
<source>Insert key</source>
|
||||
<translation>Вставити ключ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="151"/>
|
||||
<source>Insert</source>
|
||||
<translation>Вставити</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
|
||||
<source>Continue</source>
|
||||
<translation>Продовжити</translation>
|
||||
</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>
|
||||
<translation>Інші параметри підключення</translation>
|
||||
</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>
|
||||
<translation>VPN від Amnezia</translation>
|
||||
</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>
|
||||
<translation>Підключайтеся до звичайних платних та безкоштовних VPN-сервісів від Amnezia</translation>
|
||||
</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>
|
||||
<translation>Self-hosted VPN</translation>
|
||||
</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>
|
||||
<translation>Налаштуйте Amnezia VPN на власному сервері</translation>
|
||||
</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>
|
||||
<translation>Відновити із бекапа</translation>
|
||||
</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>
|
||||
<translation>Відкрити бекап файл</translation>
|
||||
</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>
|
||||
<translation>Файли резервної копії (*.backup)</translation>
|
||||
</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>
|
||||
<translation>Відкрити файл з конфігурацією</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
|
||||
<source>QR code</source>
|
||||
<translation>QR-код</translation>
|
||||
</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>
|
||||
<translation>У мене нічого нема</translation>
|
||||
</message>
|
||||
@@ -2714,7 +2721,7 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation type="vanished">Password / SSH private key</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="116"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="113"/>
|
||||
<source>Continue</source>
|
||||
<translation>Продовжити</translation>
|
||||
</message>
|
||||
@@ -2725,7 +2732,7 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
і не будуть передані чи розголошені Amnezia або будь-яким третім особам</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="173"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<source>Enter the address in the format 255.255.255.255:88</source>
|
||||
<translation>Введіть адресу в форматі 255.255.255.255:88</translation>
|
||||
</message>
|
||||
@@ -2744,42 +2751,42 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>255.255.255.255:22</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="78"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="75"/>
|
||||
<source>SSH Username</source>
|
||||
<translation>SSH Username</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="94"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="91"/>
|
||||
<source>Password or SSH private key</source>
|
||||
<translation>Пароль або SSH ключ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="144"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="141"/>
|
||||
<source>All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>Усі дані, які ви вводите, залишатимуться суворо конфіденційними та не будуть передані чи розголошені Amnezia або будь-яким третім особам</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="153"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="150"/>
|
||||
<source>How to run your VPN server</source>
|
||||
<translation>Як запустити ваш VPN-сервер</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="154"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="151"/>
|
||||
<source>Where to get connection data, step-by-step instructions for buying a VPS</source>
|
||||
<translation>Де отримати дані для підключення: покрокові інструкції з придбання VPS</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="167"/>
|
||||
<source>Ip address cannot be empty</source>
|
||||
<translation>Поле IP address не може бути пустим</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="177"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="174"/>
|
||||
<source>Login cannot be empty</source>
|
||||
<translation>Поле Login не може бути пустим</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="181"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="178"/>
|
||||
<source>Password/private key cannot be empty</source>
|
||||
<translation>Поле Password/Private key не може бути пустим</translation>
|
||||
</message>
|
||||
@@ -3163,66 +3170,71 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>Пошук</translation>
|
||||
</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>
|
||||
<translation>Дата створення: %1</translation>
|
||||
</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>
|
||||
<translation>Останнє з'єднання: %1</translation>
|
||||
</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>
|
||||
<translation>Отримано даних: %1</translation>
|
||||
</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>
|
||||
<translation>Відправлено даних: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
|
||||
<source>Allowed IPs: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Creation date: </source>
|
||||
<translation type="obsolete">Дата створення:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="862"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
|
||||
<source>Rename</source>
|
||||
<translation>Перейменувати</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="908"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
|
||||
<source>Client name</source>
|
||||
<translation>Назва клієнта</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="921"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
|
||||
<source>Save</source>
|
||||
<translation>Зберегти</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="955"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<source>Revoke</source>
|
||||
<translation>Відкликати</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="959"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
|
||||
<source>Revoke the config for a user - %1?</source>
|
||||
<translation>Відкликати доступ для користувача - %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
|
||||
<source>The user will no longer be able to connect to your server.</source>
|
||||
<translation>Користувач більше не зможе підключатись до вашого сервера </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="961"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
|
||||
<source>Continue</source>
|
||||
<translation>Продовжити</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="962"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
|
||||
<source>Cancel</source>
|
||||
<translation>Відмінити</translation>
|
||||
</message>
|
||||
@@ -3312,17 +3324,17 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<context>
|
||||
<name>PageStart</name>
|
||||
<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>
|
||||
<translation>Логування було вимкнене через 14 днів, файли журналів були видалені</translation>
|
||||
</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>
|
||||
<translation>Відновлення налаштувань із бекап файлу</translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -3721,17 +3733,17 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation type="unfinished">Конфігурація не містить контейнерів і облікових даних для підключення до серверу</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="58"/>
|
||||
<location filename="../core/errorstrings.cpp" line="59"/>
|
||||
<source>Error when retrieving configuration from API</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation>Ця конфігурація вже була додана в застосунок</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="78"/>
|
||||
<location filename="../core/errorstrings.cpp" line="80"/>
|
||||
<source>ErrorCode: %1. </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -3790,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>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="61"/>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<source>SSL error occurred</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<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="63"/>
|
||||
<location filename="../core/errorstrings.cpp" line="64"/>
|
||||
<source>Missing AGW public key</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="66"/>
|
||||
<source>QFile error: The file could not be opened</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>
|
||||
<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 accessed</source>
|
||||
<source>QFile error: The file could not be opened</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<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>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="75"/>
|
||||
<location filename="../core/errorstrings.cpp" line="77"/>
|
||||
<source>Internal error</source>
|
||||
<translation>Internal error</translation>
|
||||
</message>
|
||||
@@ -4526,7 +4548,7 @@ This means that AmneziaWG keeps the fast performance of the original while addin
|
||||
<context>
|
||||
<name>VpnConnection</name>
|
||||
<message>
|
||||
<location filename="../vpnconnection.cpp" line="408"/>
|
||||
<location filename="../vpnconnection.cpp" line="409"/>
|
||||
<source>Mbps</source>
|
||||
<translation>Mbps</translation>
|
||||
</message>
|
||||
@@ -4624,12 +4646,12 @@ This means that AmneziaWG keeps the fast performance of the original while addin
|
||||
<context>
|
||||
<name>main2</name>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="162"/>
|
||||
<location filename="../ui/qml/main2.qml" line="163"/>
|
||||
<source>Private key passphrase</source>
|
||||
<translation>Пароль для особистого ключа</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="185"/>
|
||||
<location filename="../ui/qml/main2.qml" line="186"/>
|
||||
<source>Save</source>
|
||||
<translation>Зберегти</translation>
|
||||
</message>
|
||||
|
||||
@@ -89,60 +89,60 @@
|
||||
<name>ConnectionController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.h" line="80"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="100"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="115"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="121"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="103"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="118"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="124"/>
|
||||
<source>Connect</source>
|
||||
<translation>جوڑنا</translation>
|
||||
</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>
|
||||
<translation>منتخب کردہ پروٹوکول موجودہ پلیٹ فارم پر تعاون یافتہ نہیں ہے</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="214"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="217"/>
|
||||
<source>VPN Protocols is not installed.
|
||||
Please install VPN container at first</source>
|
||||
<translation>وی پی این پروٹوکول انسٹال نہیں ہے,براہ کرم پہلےوی پی این کنٹینر انسٹال کریں</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="233"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="236"/>
|
||||
<source>unable to create configuration</source>
|
||||
<translation>تشکیل تیار کرنے میں ناکام</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="81"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="84"/>
|
||||
<source>Connecting...</source>
|
||||
<translation>جوڑاجارھاھے....</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="86"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="89"/>
|
||||
<source>Connected</source>
|
||||
<translation>جوڑاجارھاھے</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="95"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="98"/>
|
||||
<source>Reconnecting...</source>
|
||||
<translation>دوبارہ جوڑنےکی کوشش...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="105"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="108"/>
|
||||
<source>Disconnecting...</source>
|
||||
<translation>منقطع کرنا...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="110"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="113"/>
|
||||
<source>Preparing...</source>
|
||||
<translation>تیاری کیا جا رہا ہے...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="132"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<source>Settings updated successfully, reconnnection...</source>
|
||||
<translation>ترتیب ک ھوگی،دوبارہ جوڑنےکی کوشش...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="138"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>دوبارہ ترتیب تاذہ کامیاب</translation>
|
||||
</message>
|
||||
@@ -252,23 +252,20 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>ImportController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="87"/>
|
||||
<source>Unable to open file</source>
|
||||
<translation>فائل کو کھولنے سے قاصر ہے</translation>
|
||||
<translation type="vanished">فائل کو کھولنے سے قاصر ہے</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="187"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="192"/>
|
||||
<source>Invalid configuration file</source>
|
||||
<translation>غلط کنفیگریشن فائل</translation>
|
||||
<translation type="vanished">غلط کنفیگریشن فائل</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="617"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="623"/>
|
||||
<source>Scanned %1 of %2.</source>
|
||||
<translation>سکین%1 کی%2.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="652"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="658"/>
|
||||
<source>In the imported configuration, potentially dangerous lines were found:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -276,86 +273,86 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>InstallController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="181"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="157"/>
|
||||
<source>%1 installed successfully. </source>
|
||||
<translation>%1 کامیابی سےنصب. </translation>
|
||||
</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>
|
||||
<translation>%1 پہلے ہی سرور پر انسٹال ہے. </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="203"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="179"/>
|
||||
<source>
|
||||
Added containers that were already installed on the server</source>
|
||||
<translation>
|
||||
وہ کنٹینرز شامل کیے گئے جو پہلے سے سرور پر نصب تھے</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="283"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="259"/>
|
||||
<source>
|
||||
Already installed containers were found on the server. All installed containers have been added to the application</source>
|
||||
<translation>
|
||||
سرور پر پہلے سے نصب کنٹینرز پائے گئے۔ تمام نصب کنٹینرز کو ایپلی کیشن میں شامل کر دیا گیا ہے</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="541"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="517"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>ترتیب کامیابی کے ساتھ اپ ڈیٹ ہو گئی</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="558"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="534"/>
|
||||
<source>Server '%1' was rebooted</source>
|
||||
<translation>سرور %1 دوبارہ چالو کیا گیا تھا</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="570"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="546"/>
|
||||
<source>Server '%1' was removed</source>
|
||||
<translation>سرور %1 ہٹا دیا گیا تھا</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="581"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="557"/>
|
||||
<source>All containers from server '%1' have been removed</source>
|
||||
<translation>سرور '%1' سے تمام کنٹینرز ہٹا دیے گئے ہیں</translation>
|
||||
</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 '%2'</source>
|
||||
<translation>سرور '%2' سے %1 ہٹا دیا گیا ہے</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="608"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="584"/>
|
||||
<source>Api config removed</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="630"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="606"/>
|
||||
<source>%1 cached profile cleared</source>
|
||||
<translation>%1 کیش کردہ پروفائل ختم کر دی گئی</translation>
|
||||
</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>
|
||||
<translation>براہ کرم صارف کے طور پر لاگ ان کریں</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="797"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="773"/>
|
||||
<source>Server added successfully</source>
|
||||
<translation>سرور کامیابی سے شامل کیا گیا</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="845"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="821"/>
|
||||
<source>%1 installed successfully.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="877"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="855"/>
|
||||
<source>API config reloaded</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -399,30 +396,30 @@ Already installed containers were found on the server. All installed containers
|
||||
<context>
|
||||
<name>NotificationHandler</name>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="63"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="70"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<source>AmneziaVPN</source>
|
||||
<translation>The translation of "AmneziaVPN" in Urdu would be:
|
||||
|
||||
امنیزیا وی پی ای</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="65"/>
|
||||
<source>VPN Connected</source>
|
||||
<translation>وی پی این متصل ہوگیا</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="72"/>
|
||||
<source>VPN Disconnected</source>
|
||||
<translation>وی پی این منقطع ہوگیا</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="94"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<source>AmneziaVPN notification</source>
|
||||
<translation>امنیزیا وی پی این کی اطلاعات</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="96"/>
|
||||
<source>Unsecured network detected: </source>
|
||||
<translation>غیر محفوظ نیٹ ورک کا پتہ لگایا گیا ہے: </translation>
|
||||
</message>
|
||||
@@ -2386,97 +2383,107 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation type="vanished">کنکشن کی ترتیبات یا بیک اپ والی فائل</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
|
||||
<source>Connection</source>
|
||||
<translation type="unfinished">کنکشن</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
|
||||
<source>Settings</source>
|
||||
<translation type="unfinished">ترتیبات</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
|
||||
<source>Enable logs</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/>
|
||||
<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="122"/>
|
||||
<source>Insert key</source>
|
||||
<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>
|
||||
<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>
|
||||
<translation type="unfinished">داخل کریں</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
|
||||
<source>Continue</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation type="unfinished">بیک اپ سے بحال کریں</translation>
|
||||
</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>
|
||||
<translation type="unfinished">بیک اپ فائل کو کھولیں</translation>
|
||||
</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>
|
||||
<translation type="unfinished">بیک اپ فائلیں (*.backup)</translation>
|
||||
</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>
|
||||
<translation>کنکشن کی ترتیبات والی فائل</translation>
|
||||
</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>
|
||||
<translation>کنفیگ فائل کو کھولیں</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
|
||||
<source>QR code</source>
|
||||
<translation>QR کوڈ</translation>
|
||||
</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>
|
||||
<translation type="unfinished">میرے پاس کچھ نہیں ہے</translation>
|
||||
</message>
|
||||
@@ -2498,12 +2505,12 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>سرور آئی پی پتہ [:پورٹ]</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="116"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="113"/>
|
||||
<source>Continue</source>
|
||||
<translation>براہ کرم جاری رکھیں</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="144"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="141"/>
|
||||
<source>All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>آپ جو ڈیٹا داخل کریں گے وہ بالکل خفیہ رہے گا اور نہ تو امنیزیا یا کسی تیسری شخصیت کے ساتھ اشتراک کیا جائے گا</translation>
|
||||
</message>
|
||||
@@ -2513,42 +2520,42 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="78"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="75"/>
|
||||
<source>SSH Username</source>
|
||||
<translation>ایس ایس ایچ صارف نام</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="94"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="91"/>
|
||||
<source>Password or SSH private key</source>
|
||||
<translation>پاس ورڈ یا SSH نجی کلید</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="153"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="150"/>
|
||||
<source>How to run your VPN server</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="154"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="151"/>
|
||||
<source>Where to get connection data, step-by-step instructions for buying a VPS</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="167"/>
|
||||
<source>Ip address cannot be empty</source>
|
||||
<translation>آئی پی پتہ خالی نہیں ہو سکتا</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="173"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<source>Enter the address in the format 255.255.255.255:88</source>
|
||||
<translation>ایڈریس درج کریں فارمیٹ 255.255.255.255:88</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="177"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="174"/>
|
||||
<source>Login cannot be empty</source>
|
||||
<translation>لاگ ان نام خالی نہیں ہو سکتا</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="181"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="178"/>
|
||||
<source>Password/private key cannot be empty</source>
|
||||
<translation>پاس ورڈ یا نجی کلید خالی نہیں ہو سکتی</translation>
|
||||
</message>
|
||||
@@ -2861,66 +2868,71 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>تلاش</translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
|
||||
<source>Allowed IPs: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Creation date: </source>
|
||||
<translation type="vanished">تخلیق کی تاریخ: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="862"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
|
||||
<source>Rename</source>
|
||||
<translation>نام تبدیل</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="908"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
|
||||
<source>Client name</source>
|
||||
<translation>کلائنٹ کا نام</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="921"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
|
||||
<source>Save</source>
|
||||
<translation>محفوظ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="955"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<source>Revoke</source>
|
||||
<translation>واپس لین</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="959"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
|
||||
<source>Revoke the config for a user - %1?</source>
|
||||
<translation>کیا آپ مستعمل کے لئے کنفیگ کو واپس لینا چاہتے ہیں - %1؟</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
|
||||
<source>The user will no longer be able to connect to your server.</source>
|
||||
<translation>صارف آپ کے سرور سے متصل ہونے کا اختیار نہیں رہے گا.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="961"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
|
||||
<source>Continue</source>
|
||||
<translation>جاری رکھیں</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="962"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
|
||||
<source>Cancel</source>
|
||||
<translation>منسوخ</translation>
|
||||
</message>
|
||||
@@ -3038,17 +3050,17 @@ Already installed containers were found on the server. All installed containers
|
||||
<context>
|
||||
<name>PageStart</name>
|
||||
<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>
|
||||
<translation>لاگنگ کو 14 دنوں کے بعد غیر فعال کر دیا گیا، لاگ فائلوں کو حذف کر دیا گیا</translation>
|
||||
</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>
|
||||
<translation type="unfinished">ترتیبات بیک اپ فائل سے بحال کردی گئی ہیں</translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -3387,22 +3399,22 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>سرور سے منسلک ہونے کا ٹائم آؤٹ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="55"/>
|
||||
<location filename="../core/errorstrings.cpp" line="56"/>
|
||||
<source>VPN connection error</source>
|
||||
<translation>VPN کنکشن کی خرابی</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="58"/>
|
||||
<location filename="../core/errorstrings.cpp" line="59"/>
|
||||
<source>Error when retrieving configuration from API</source>
|
||||
<translation>آپی سے کنفیگریشن بازیافت کرتے وقت خرابی</translation>
|
||||
</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>
|
||||
<translation>یہ تشکیل پہلے ہی ایپلی کیشن میں شامل کی جا چکی ہے</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="78"/>
|
||||
<location filename="../core/errorstrings.cpp" line="80"/>
|
||||
<source>ErrorCode: %1. </source>
|
||||
<translation>ایرر کوڈ: %1. </translation>
|
||||
</message>
|
||||
@@ -3477,57 +3489,67 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>ترتیب میں سرور سے منسلک ہونے کے لیے کوئی کنٹینرز اور اسناد نہیں ہیں</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="60"/>
|
||||
<source>In the response from the server, an empty config was received</source>
|
||||
<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>SSL error occurred</source>
|
||||
<source>In the response from the server, an empty config was received</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<source>Server response timeout on api request</source>
|
||||
<source>SSL error occurred</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<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>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation>QFile کی خرابی: فائل کو نہیں کھولا جا سکا</translation>
|
||||
</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>
|
||||
<translation>کیو فائل کی خرابی: فائل سے پڑھتے وقت ایک خرابی پیش آگئی</translation>
|
||||
</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>
|
||||
<translation>QFile کی خرابی: فائل تک رسائی نہیں ہو سکی</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="69"/>
|
||||
<location filename="../core/errorstrings.cpp" line="71"/>
|
||||
<source>QFile error: An unspecified error occurred</source>
|
||||
<translation>کیو فائل میں خرابی: ایک غیر متعینہ خرابی پیش آگئی</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="70"/>
|
||||
<location filename="../core/errorstrings.cpp" line="72"/>
|
||||
<source>QFile error: A fatal error occurred</source>
|
||||
<translation>کیو فائل میں خرابی: ایک مہلک خرابی پیش آگئی</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="71"/>
|
||||
<location filename="../core/errorstrings.cpp" line="73"/>
|
||||
<source>QFile error: The operation was aborted</source>
|
||||
<translation>کیو فائل کی خرابی: آپریشن روک دیا گیا تھا</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="75"/>
|
||||
<location filename="../core/errorstrings.cpp" line="77"/>
|
||||
<source>Internal error</source>
|
||||
<translation>داخلی خامی</translation>
|
||||
</message>
|
||||
@@ -4068,7 +4090,7 @@ While it offers a blend of security, stability, and speed, it's essential t
|
||||
<context>
|
||||
<name>VpnConnection</name>
|
||||
<message>
|
||||
<location filename="../vpnconnection.cpp" line="408"/>
|
||||
<location filename="../vpnconnection.cpp" line="409"/>
|
||||
<source>Mbps</source>
|
||||
<translation>ایم بی پی ایس</translation>
|
||||
</message>
|
||||
@@ -4154,12 +4176,12 @@ While it offers a blend of security, stability, and speed, it's essential t
|
||||
<context>
|
||||
<name>main2</name>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="162"/>
|
||||
<location filename="../ui/qml/main2.qml" line="163"/>
|
||||
<source>Private key passphrase</source>
|
||||
<translation>نجی کلید پاس فریز</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="185"/>
|
||||
<location filename="../ui/qml/main2.qml" line="186"/>
|
||||
<source>Save</source>
|
||||
<translation>محفوظ کریں</translation>
|
||||
</message>
|
||||
|
||||
@@ -89,60 +89,60 @@
|
||||
<name>ConnectionController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.h" line="80"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="100"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="115"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="121"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="103"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="118"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="124"/>
|
||||
<source>Connect</source>
|
||||
<translation>连接</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="214"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="217"/>
|
||||
<source>VPN Protocols is not installed.
|
||||
Please install VPN container at first</source>
|
||||
<translation>请先安装VPN协议</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="81"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="84"/>
|
||||
<source>Connecting...</source>
|
||||
<translation>连接中</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="86"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="89"/>
|
||||
<source>Connected</source>
|
||||
<translation>已连接</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="95"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="98"/>
|
||||
<source>Reconnecting...</source>
|
||||
<translation>重连中</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="105"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="108"/>
|
||||
<source>Disconnecting...</source>
|
||||
<translation>断开中</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="110"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="113"/>
|
||||
<source>Preparing...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="132"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<source>Settings updated successfully, reconnnection...</source>
|
||||
<translation>配置已更新, 重连中...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="138"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>配置更新成功</translation>
|
||||
</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>
|
||||
<translation type="unfinished">当前平台不支持所选协议</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="233"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="236"/>
|
||||
<source>unable to create configuration</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -257,23 +257,12 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>ImportController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="87"/>
|
||||
<source>Unable to open file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="187"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="192"/>
|
||||
<source>Invalid configuration file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="617"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="623"/>
|
||||
<source>Scanned %1 of %2.</source>
|
||||
<translation>扫描 %1 of %2.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="652"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="658"/>
|
||||
<source>In the imported configuration, potentially dangerous lines were found:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -289,75 +278,75 @@ Can't be disabled for current server</source>
|
||||
<translation type="obsolete"> 已安装在服务器上</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="181"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="157"/>
|
||||
<source>%1 installed successfully. </source>
|
||||
<translation>%1 安装成功。</translation>
|
||||
</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>
|
||||
<translation>服务器上已经安装 %1。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="203"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="179"/>
|
||||
<source>
|
||||
Added containers that were already installed on the server</source>
|
||||
<translation>添加已安装在服务器上的容器</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="283"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="259"/>
|
||||
<source>
|
||||
Already installed containers were found on the server. All installed containers have been added to the application</source>
|
||||
<translation>
|
||||
在服务上发现已经安装协议并添加至应用</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="541"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="517"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>配置更新成功</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="558"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="534"/>
|
||||
<source>Server '%1' was rebooted</source>
|
||||
<translation>服务器 '%1' 已重新启动</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="570"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="546"/>
|
||||
<source>Server '%1' was removed</source>
|
||||
<translation>已移除服务器 '%1'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="581"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="557"/>
|
||||
<source>All containers from server '%1' have been removed</source>
|
||||
<translation>服务器 '%1' 的所有容器已移除</translation>
|
||||
</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 '%2'</source>
|
||||
<translation>%1 已从服务器 '%2' 上移除</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="608"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="584"/>
|
||||
<source>Api config removed</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="630"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="606"/>
|
||||
<source>%1 cached profile cleared</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="845"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="821"/>
|
||||
<source>%1 installed successfully.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="877"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="855"/>
|
||||
<source>API config reloaded</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -378,12 +367,12 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation type="obsolete"> 协议已从</translation>
|
||||
</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>
|
||||
<translation>请以用户身份登录</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="797"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="773"/>
|
||||
<source>Server added successfully</source>
|
||||
<translation>增加服务器成功</translation>
|
||||
</message>
|
||||
@@ -427,28 +416,28 @@ Already installed containers were found on the server. All installed containers
|
||||
<context>
|
||||
<name>NotificationHandler</name>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="63"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="70"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<source>AmneziaVPN</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="65"/>
|
||||
<source>VPN Connected</source>
|
||||
<translation>已连接到VPN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="72"/>
|
||||
<source>VPN Disconnected</source>
|
||||
<translation>已从VPN断开</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="94"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<source>AmneziaVPN notification</source>
|
||||
<translation>AmneziaVPN 提示</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="96"/>
|
||||
<source>Unsecured network detected: </source>
|
||||
<translation>发现不安全网络</translation>
|
||||
</message>
|
||||
@@ -2549,97 +2538,107 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation type="vanished">包含连接配置或备份的文件</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
|
||||
<source>Connection</source>
|
||||
<translation type="unfinished">连接</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
|
||||
<source>Settings</source>
|
||||
<translation type="unfinished">设置</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
|
||||
<source>Enable logs</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/>
|
||||
<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="122"/>
|
||||
<source>Insert key</source>
|
||||
<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>
|
||||
<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>
|
||||
<translation type="unfinished">插入</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
|
||||
<source>Continue</source>
|
||||
<translation type="unfinished">继续</translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation type="unfinished">从备份还原</translation>
|
||||
</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>
|
||||
<translation type="unfinished">打开备份文件</translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation>包含连接配置的文件</translation>
|
||||
</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>
|
||||
<translation>打开配置文件</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
|
||||
<source>QR code</source>
|
||||
<translation>二维码</translation>
|
||||
</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>
|
||||
<translation type="unfinished">我没有</translation>
|
||||
</message>
|
||||
@@ -2673,12 +2672,12 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation type="vanished">密码 或 私钥</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="116"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="113"/>
|
||||
<source>Continue</source>
|
||||
<translation>继续</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="144"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="141"/>
|
||||
<source>All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>您输入的所有数据将严格保密,不会与 Amnezia 或任何第三方共享或披露</translation>
|
||||
</message>
|
||||
@@ -2694,42 +2693,42 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="78"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="75"/>
|
||||
<source>SSH Username</source>
|
||||
<translation>SSH 用户名</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="94"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="91"/>
|
||||
<source>Password or SSH private key</source>
|
||||
<translation>密码或 SSH 私钥</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="153"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="150"/>
|
||||
<source>How to run your VPN server</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="154"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="151"/>
|
||||
<source>Where to get connection data, step-by-step instructions for buying a VPS</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="167"/>
|
||||
<source>Ip address cannot be empty</source>
|
||||
<translation>IP不能为空</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="173"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<source>Enter the address in the format 255.255.255.255:88</source>
|
||||
<translation>按照这种格式输入 255.255.255.255:88</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="177"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="174"/>
|
||||
<source>Login cannot be empty</source>
|
||||
<translation>账号不能为空</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="181"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="178"/>
|
||||
<source>Password/private key cannot be empty</source>
|
||||
<translation>密码或私钥不能为空</translation>
|
||||
</message>
|
||||
@@ -3067,66 +3066,71 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>搜索</translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
|
||||
<source>Allowed IPs: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Creation date: </source>
|
||||
<translation type="vanished">创建日期: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="862"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
|
||||
<source>Rename</source>
|
||||
<translation>重新命名</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="908"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
|
||||
<source>Client name</source>
|
||||
<translation>客户名称</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="921"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
|
||||
<source>Save</source>
|
||||
<translation>保存</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="955"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<source>Revoke</source>
|
||||
<translation>撤销</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="959"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
|
||||
<source>Revoke the config for a user - %1?</source>
|
||||
<translation>撤销用户的配置- %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
|
||||
<source>The user will no longer be able to connect to your server.</source>
|
||||
<translation>该用户将无法再连接到您的服务器.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="961"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
|
||||
<source>Continue</source>
|
||||
<translation>继续</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="962"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
|
||||
<source>Cancel</source>
|
||||
<translation>取消</translation>
|
||||
</message>
|
||||
@@ -3283,17 +3287,17 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<context>
|
||||
<name>PageStart</name>
|
||||
<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>
|
||||
<translation type="unfinished"></translation>
|
||||
</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>
|
||||
<translation type="unfinished">从备份文件还原配置</translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -3646,6 +3650,11 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<source>SCP error: Generic failure</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="53"/>
|
||||
<source>Unable to open config file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sftp error: End-of-file encountered</source>
|
||||
<translation type="vanished">Sftp错误: End-of-file encountered</translation>
|
||||
@@ -3699,72 +3708,77 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation type="vanished">Sftp 错误: 远程驱动器中没有媒介</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="55"/>
|
||||
<location filename="../core/errorstrings.cpp" line="56"/>
|
||||
<source>VPN connection error</source>
|
||||
<translation>VPN 连接错误</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="58"/>
|
||||
<location filename="../core/errorstrings.cpp" line="59"/>
|
||||
<source>Error when retrieving configuration from API</source>
|
||||
<translation>从 API 检索配置时出错</translation>
|
||||
</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>
|
||||
<translation>该配置已添加到应用程序中</translation>
|
||||
</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>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="61"/>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<source>SSL error occurred</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<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="63"/>
|
||||
<location filename="../core/errorstrings.cpp" line="64"/>
|
||||
<source>Missing AGW public key</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="66"/>
|
||||
<source>QFile error: The file could not be opened</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>
|
||||
<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 accessed</source>
|
||||
<source>QFile error: The file could not be opened</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<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>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="78"/>
|
||||
<location filename="../core/errorstrings.cpp" line="80"/>
|
||||
<source>ErrorCode: %1. </source>
|
||||
<translation>错误代码: %1. </translation>
|
||||
</message>
|
||||
@@ -3832,7 +3846,7 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation type="vanished">该配置不包含任何用于连接到服务器的容器和凭据。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="75"/>
|
||||
<location filename="../core/errorstrings.cpp" line="77"/>
|
||||
<source>Internal error</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
@@ -4512,7 +4526,7 @@ While it offers a blend of security, stability, and speed, it's essential t
|
||||
<context>
|
||||
<name>VpnConnection</name>
|
||||
<message>
|
||||
<location filename="../vpnconnection.cpp" line="408"/>
|
||||
<location filename="../vpnconnection.cpp" line="409"/>
|
||||
<source>Mbps</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
@@ -4610,12 +4624,12 @@ While it offers a blend of security, stability, and speed, it's essential t
|
||||
<context>
|
||||
<name>main2</name>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="162"/>
|
||||
<location filename="../ui/qml/main2.qml" line="163"/>
|
||||
<source>Private key passphrase</source>
|
||||
<translation>私钥密码</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="185"/>
|
||||
<location filename="../ui/qml/main2.qml" line="186"/>
|
||||
<source>Save</source>
|
||||
<translation>保存</translation>
|
||||
</message>
|
||||
|
||||
@@ -34,13 +34,13 @@ ConnectionController::ConnectionController(const QSharedPointer<ServersModel> &s
|
||||
|
||||
void ConnectionController::openConnection()
|
||||
{
|
||||
// #if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||
// if (!Utils::processIsRunning(Utils::executable(SERVICE_NAME, false), true))
|
||||
// {
|
||||
// emit connectionErrorOccurred(ErrorCode::AmneziaServiceNotRunning);
|
||||
// return;
|
||||
// }
|
||||
// #endif
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||
if (!Utils::processIsRunning(Utils::executable(SERVICE_NAME, false), true))
|
||||
{
|
||||
emit connectionErrorOccurred(ErrorCode::AmneziaServiceNotRunning);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
int serverIndex = m_serversModel->getDefaultServerIndex();
|
||||
QJsonObject serverConfig = m_serversModel->getServerConfig(serverIndex);
|
||||
@@ -51,6 +51,9 @@ void ConnectionController::openConnection()
|
||||
if (configVersion == ApiConfigSources::Telegram
|
||||
&& !m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
|
||||
emit updateApiConfigFromTelegram();
|
||||
} else if (configVersion == ApiConfigSources::AmneziaGateway
|
||||
&& !m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
|
||||
emit updateApiConfigFromGateway();
|
||||
} else if (configVersion && m_serversModel->isApiKeyExpired(serverIndex)) {
|
||||
qDebug() << "attempt to update api config by end_date event";
|
||||
if (configVersion == ApiConfigSources::Telegram) {
|
||||
|
||||
@@ -39,11 +39,12 @@ namespace
|
||||
const QString amneziaConfigPatternUserName = "userName";
|
||||
const QString amneziaConfigPatternPassword = "password";
|
||||
const QString amneziaFreeConfigPattern = "api_key";
|
||||
const QString amneziaPremiumConfigPattern = "auth_data";
|
||||
const QString backupPattern = "Servers/serversList";
|
||||
|
||||
if (config.contains(backupPattern)) {
|
||||
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(amneziaConfigPatternPassword))) {
|
||||
return ConfigTypes::Amnezia;
|
||||
@@ -84,7 +85,7 @@ bool ImportController::extractConfigFromFile(const QString &fileName)
|
||||
return extractConfigFromData(data);
|
||||
}
|
||||
|
||||
emit importErrorOccurred(tr("Unable to open file"), false);
|
||||
emit importErrorOccurred(ErrorCode::ImportOpenConfigError, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -188,12 +189,12 @@ bool ImportController::extractConfigFromData(QString data)
|
||||
if (!m_serversModel->getServersCount()) {
|
||||
emit restoreAppConfig(config.toUtf8());
|
||||
} else {
|
||||
emit importErrorOccurred(tr("Invalid configuration file"), false);
|
||||
emit importErrorOccurred(ErrorCode::ImportInvalidConfigError, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ConfigTypes::Invalid: {
|
||||
emit importErrorOccurred(tr("Invalid configuration file"), false);
|
||||
emit importErrorOccurred(ErrorCode::ImportInvalidConfigError, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,6 @@ public slots:
|
||||
|
||||
signals:
|
||||
void importFinished();
|
||||
void importErrorOccurred(const QString &errorMessage, bool goToPageHome);
|
||||
void importErrorOccurred(ErrorCode errorCode, bool goToPageHome);
|
||||
|
||||
void qrDecodingFinished();
|
||||
|
||||
48
client/ui/controllers/installController.cpp
Normal file → Executable file
@@ -32,32 +32,8 @@ namespace
|
||||
constexpr char availableCountries[] = "available_countries";
|
||||
|
||||
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,
|
||||
@@ -135,10 +111,10 @@ void InstallController::install(DockerContainer container, int port, TransportPr
|
||||
containerConfig[config_key::transportPacketMagicHeader] = transportPacketMagicHeader;
|
||||
} else if (container == DockerContainer::Sftp) {
|
||||
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) {
|
||||
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));
|
||||
@@ -667,7 +643,7 @@ void InstallController::mountSftpDrive(const QString &port, const QString &passw
|
||||
QString hostname = serverCredentials.hostName;
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
mountPath = getNextDriverLetter() + ":";
|
||||
mountPath = Utils::getNextDriverLetter() + ":";
|
||||
// QString cmd = QString("net use \\\\sshfs\\%1@x.x.x.x!%2 /USER:%1 %3")
|
||||
// .arg(labelTftpUserNameText())
|
||||
// .arg(labelTftpPortText())
|
||||
@@ -768,7 +744,7 @@ bool InstallController::checkSshConnection(QSharedPointer<ServerController> serv
|
||||
} else {
|
||||
if (output.contains(tr("Please login as the user"))) {
|
||||
output.replace("\n", "");
|
||||
emit installationErrorOccurred(output);
|
||||
emit wrongInstallationUser(output);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -826,7 +802,7 @@ bool InstallController::installServiceFromApi()
|
||||
|
||||
ErrorCode errorCode = apiController.getConfigForService(m_settings->getInstallationUuid(true), m_apiServicesModel->getCountryCode(),
|
||||
m_apiServicesModel->getSelectedServiceType(),
|
||||
m_apiServicesModel->getSelectedServiceProtocol(), "", serverConfig);
|
||||
m_apiServicesModel->getSelectedServiceProtocol(), "", QJsonObject(), serverConfig);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
emit installationErrorOccurred(errorCode);
|
||||
return false;
|
||||
@@ -853,24 +829,26 @@ bool InstallController::updateServiceFromApi(const int serverIndex, const QStrin
|
||||
|
||||
auto serverConfig = m_serversModel->getServerConfig(serverIndex);
|
||||
auto apiConfig = serverConfig.value(configKey::apiConfig).toObject();
|
||||
auto authData = serverConfig.value(configKey::authData).toObject();
|
||||
|
||||
QJsonObject newServerConfig;
|
||||
ErrorCode errorCode =
|
||||
apiController.getConfigForService(m_settings->getInstallationUuid(true), apiConfig.value(configKey::userCountryCode).toString(),
|
||||
apiConfig.value(configKey::serviceType).toString(),
|
||||
apiConfig.value(configKey::serviceProtocol).toString(), newCountryCode, newServerConfig);
|
||||
ErrorCode errorCode = apiController.getConfigForService(
|
||||
m_settings->getInstallationUuid(true), apiConfig.value(configKey::userCountryCode).toString(),
|
||||
apiConfig.value(configKey::serviceType).toString(), apiConfig.value(configKey::serviceProtocol).toString(), newCountryCode,
|
||||
authData, newServerConfig);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
emit installationErrorOccurred(errorCode);
|
||||
return false;
|
||||
}
|
||||
|
||||
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::serviceType, apiConfig.value(configKey::serviceType));
|
||||
newApiConfig.insert(configKey::serviceProtocol, apiConfig.value(configKey::serviceProtocol));
|
||||
|
||||
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);
|
||||
|
||||
if (reloadServiceConfig) {
|
||||
|
||||
@@ -75,8 +75,8 @@ signals:
|
||||
void removeAllContainersFinished(const QString &finishedMessage);
|
||||
void removeProcessedContainerFinished(const QString &finishedMessage);
|
||||
|
||||
void installationErrorOccurred(const QString &errorMessage);
|
||||
void installationErrorOccurred(ErrorCode errorCode);
|
||||
void wrongInstallationUser(const QString &message);
|
||||
|
||||
void serverAlreadyExists(int serverIndex);
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ PageController::PageController(const QSharedPointer<ServersModel> &serversModel,
|
||||
AndroidController::instance()->setNavigationBarColor(initialPageNavigationBarColor);
|
||||
#endif
|
||||
|
||||
#if defined Q_OS_MACX
|
||||
#if defined Q_OS_MACX and !defined MACOS_NE
|
||||
connect(this, &PageController::raiseMainWindow, []() { setDockIconVisible(true); });
|
||||
connect(this, &PageController::hideMainWindow, []() { setDockIconVisible(false); });
|
||||
#endif
|
||||
@@ -114,7 +114,7 @@ void PageController::showOnStartup()
|
||||
} else {
|
||||
#if defined(Q_OS_WIN) || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
emit hideMainWindow();
|
||||
#elif defined Q_OS_MACX
|
||||
#elif defined Q_OS_MACX and !defined MACOS_NE
|
||||
setDockIconVisible(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -39,6 +39,9 @@ QVariant ApiCountryModel::data(const QModelIndex &index, int role) const
|
||||
case CountryNameRole: {
|
||||
return countryInfo.value(configKey::serverCountryName).toString();
|
||||
}
|
||||
case CountryImageCodeRole: {
|
||||
return countryInfo.value(configKey::serverCountryCode).toString().toUpper();
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
@@ -76,5 +79,6 @@ QHash<int, QByteArray> ApiCountryModel::roleNames() const
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[CountryNameRole] = "countryName";
|
||||
roles[CountryCodeRole] = "countryCode";
|
||||
roles[CountryImageCodeRole] = "countryImageCode";
|
||||
return roles;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,8 @@ class ApiCountryModel : public QAbstractListModel
|
||||
public:
|
||||
enum Roles {
|
||||
CountryNameRole = Qt::UserRole + 1,
|
||||
CountryCodeRole
|
||||
CountryCodeRole,
|
||||
CountryImageCodeRole
|
||||
};
|
||||
|
||||
explicit ApiCountryModel(QObject *parent = nullptr);
|
||||
|
||||
@@ -77,6 +77,7 @@ ErrorCode ClientManagementModel::updateModel(const DockerContainer container, co
|
||||
{
|
||||
beginResetModel();
|
||||
m_clientsTable = QJsonArray();
|
||||
endResetModel();
|
||||
|
||||
ErrorCode error = ErrorCode::NoError;
|
||||
|
||||
@@ -90,10 +91,10 @@ ErrorCode ClientManagementModel::updateModel(const DockerContainer container, co
|
||||
const QByteArray clientsTableString = serverController->getTextFileFromContainer(container, credentials, clientsTableFile, error);
|
||||
if (error != ErrorCode::NoError) {
|
||||
logger.error() << "Failed to get the clientsTable file from the server";
|
||||
endResetModel();
|
||||
return error;
|
||||
}
|
||||
|
||||
beginResetModel();
|
||||
m_clientsTable = QJsonDocument::fromJson(clientsTableString).array();
|
||||
|
||||
if (m_clientsTable.isEmpty()) {
|
||||
@@ -601,5 +602,6 @@ QHash<int, QByteArray> ClientManagementModel::roleNames() const
|
||||
roles[LatestHandshakeRole] = "latestHandshake";
|
||||
roles[DataReceivedRole] = "dataReceived";
|
||||
roles[DataSentRole] = "dataSent";
|
||||
roles[AllowedIpsRole] = "allowedIps";
|
||||
return roles;
|
||||
}
|
||||
|
||||
@@ -771,5 +771,5 @@ const QString ServersModel::getDefaultServerImagePathCollapsed()
|
||||
if (countryCode.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
return QString("qrc:/countriesFlags/images/flagKit/%1.svg").arg(countryCode);
|
||||
return QString("qrc:/countriesFlags/images/flagKit/%1.svg").arg(countryCode.toUpper());
|
||||
}
|
||||
|
||||
@@ -5,12 +5,13 @@
|
||||
#include <QDebug>
|
||||
#include "notificationhandler.h"
|
||||
|
||||
#if defined(Q_OS_IOS)
|
||||
#if defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
# include "platforms/ios/iosnotificationhandler.h"
|
||||
#else
|
||||
# include "systemtray_notificationhandler.h"
|
||||
#endif
|
||||
|
||||
|
||||
// static
|
||||
NotificationHandler* NotificationHandler::create(QObject* parent) {
|
||||
#if defined(Q_OS_IOS)
|
||||
|
||||