1
0
mirror of https://github.com/MGislv/NekoX.git synced 2024-07-02 10:33:36 +00:00

Simple proxy switcher

(cherry picked from commit dbe6fcc50a)
This commit is contained in:
世界 2020-06-27 05:36:00 +00:00
parent 10e526ba25
commit abba7ef236
No known key found for this signature in database
GPG Key ID: CD109927C34A63C4
30 changed files with 283 additions and 214 deletions

View File

@ -44,9 +44,9 @@ dependencies {
// TODO: fix problem with android L
implementation 'com.google.zxing:core:3.4.0'
compileOnly 'org.checkerframework:checker-qual:2.5.2'
compileOnly 'org.checkerframework:checker-compat-qual:2.5.0'
implementation 'com.googlecode.mp4parser:isoparser:1.0.6'
compileOnly 'org.checkerframework:checker-qual:3.4.1'
compileOnly 'org.checkerframework:checker-compat-qual:2.5.5'
implementation 'com.googlecode.mp4parser:isoparser:1.1.22'
implementation 'com.stripe:stripe-android:2.0.2'
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'org.osmdroid:osmdroid-android:6.1.6'

View File

@ -42,6 +42,7 @@ import java.util.Set;
import tw.nekomimi.nekogram.ExternalGcm;
import tw.nekomimi.nekogram.NekoConfig;
import tw.nekomimi.nekogram.database.WarppedPref;
import tw.nekomimi.nekogram.parts.ProxySwitcher;
import tw.nekomimi.nekogram.utils.EnvUtil;
import tw.nekomimi.nekogram.utils.FileUtil;
import tw.nekomimi.nekogram.utils.ProxyUtil;
@ -306,7 +307,6 @@ public class ApplicationLoader extends Application {
}
ApplicationLoader app = (ApplicationLoader) ApplicationLoader.applicationContext;
ExternalGcm.initPlayServices();
if (BuildVars.LOGS_ENABLED) {
FileLog.d("app initied");
@ -322,6 +322,7 @@ public class ApplicationLoader extends Application {
if (finalA == UserConfig.selectedAccount) initRunnable.run();
else UIUtil.runOnIoDispatcher(initRunnable);
}
}
public ApplicationLoader() {

View File

@ -4699,7 +4699,7 @@ public class MessagesController extends BaseController implements NotificationCe
} else if (response instanceof TLRPC.TL_help_promoData) {
final TLRPC.TL_help_promoData res = (TLRPC.TL_help_promoData) response;
if (res.proxy && NekoConfig.hideProxySponsorChannel) {
if (res.proxy && (NekoConfig.hideProxySponsorChannel || (SharedConfig.currentProxy != null || SharedConfig.currentProxy.subId == 1L))) {
nextPromoInfoCheckTime = getConnectionsManager().getCurrentTime() + 60 * 60;
noDialog = true;
} else {
@ -5353,7 +5353,7 @@ public class MessagesController extends BaseController implements NotificationCe
}
public void processLoadedMessages(TLRPC.messages_Messages messagesRes, long dialogId, long mergeDialogId, int count, int max_id, int offset_date, boolean isCache, int classGuid,
int first_unread, int last_message_id, int unread_count, int last_date, int load_type, boolean isChannel, boolean isEnd, boolean scheduled, int loadIndex, boolean queryFromServer, int mentionsCount) {
int first_unread, int last_message_id, int unread_count, int last_date, int load_type, boolean isChannel, boolean isEnd, boolean scheduled, int loadIndex, boolean queryFromServer, int mentionsCount) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("processLoadedMessages size " + messagesRes.messages.size() + " in chat " + dialogId + " count " + count + " max_id " + max_id + " cache " + isCache + " guid " + classGuid + " load_type " + load_type + " last_message_id " + last_message_id + " isChannel " + isChannel + " index " + loadIndex + " firstUnread " + first_unread + " unread_count " + unread_count + " last_date " + last_date + " queryFromServer " + queryFromServer);
}

View File

@ -49,6 +49,7 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import tw.nekomimi.nekogram.NekoConfig;
import tw.nekomimi.nekogram.parts.ProxySwitcher;
import tw.nekomimi.nekogram.utils.DnsFactory;
import tw.nekomimi.nekogram.utils.UIUtil;
@ -489,6 +490,7 @@ public class ConnectionsManager extends BaseController {
getInstance(currentAccount).connectionState = state;
AccountInstance.getInstance(currentAccount).getNotificationCenter().postNotificationName(NotificationCenter.didUpdateConnectionState);
});
ProxySwitcher.didReceivedNotification(state);
}
public static void onLogout(final int currentAccount) {

View File

@ -819,8 +819,12 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
subInfo.lastFetch = System.currentTimeMillis();
SubManager.getSubList().update(subInfo, true);
SharedConfig.reloadProxyList();
} catch (SubInfo.AllTriesFailed allTriesFailed) {
FileLog.e(allTriesFailed);
}
}

View File

@ -824,7 +824,8 @@ public class ProxyListActivity extends BaseFragment implements NotificationCente
}
@SuppressLint("NewApi") private void addProxy() {
@SuppressLint("NewApi")
private void addProxy() {
BottomSheet.Builder builder = new BottomSheet.Builder(getParentActivity());
@ -1033,10 +1034,6 @@ public class ProxyListActivity extends BaseFragment implements NotificationCente
public void checkSingleProxy(SharedConfig.ProxyInfo proxyInfo, int repeat, Runnable callback) {
proxyInfo.checking = true;
UIUtil.runOnUIThread(() -> NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.proxyCheckDone, proxyInfo));
UIUtil.runOnIoDispatcher(() -> {
if (proxyInfo instanceof SharedConfig.ExternalSocks5Proxy && !((SharedConfig.ExternalSocks5Proxy) proxyInfo).isStarted()) {
@ -1057,11 +1054,11 @@ public class ProxyListActivity extends BaseFragment implements NotificationCente
}
proxyInfo.proxyCheckPingId = ConnectionsManager.getInstance(currentAccount).checkProxy(proxyInfo.address, proxyInfo.port, proxyInfo.username, proxyInfo.password, proxyInfo.secret, time -> AndroidUtilities.runOnUIThread(() -> {
proxyInfo.availableCheckTime = SystemClock.elapsedRealtime();
if (time == -1) {
if (repeat > 0) {
checkSingleProxy(proxyInfo, repeat - 1, callback);
} else {
proxyInfo.availableCheckTime = SystemClock.elapsedRealtime();
proxyInfo.checking = false;
proxyInfo.available = false;
proxyInfo.ping = 0;
@ -1073,6 +1070,7 @@ public class ProxyListActivity extends BaseFragment implements NotificationCente
}
}
} else {
proxyInfo.availableCheckTime = SystemClock.elapsedRealtime();
proxyInfo.checking = false;
proxyInfo.ping = time;
proxyInfo.available = true;

View File

@ -900,14 +900,14 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter
questionRow = -1;
faqRow = rowCount++;
policyRow = -1;
if (BuildVars.DEBUG_VERSION) {
if (BuildVars.LOGS_ENABLED) {
helpSectionCell = rowCount++;
debugHeaderRow = rowCount++;
} else {
helpSectionCell = -1;
debugHeaderRow = -1;
}
if (BuildVars.DEBUG_VERSION) {
if (BuildVars.LOGS_ENABLED) {
sendLogsRow = rowCount++;
clearLogsRow = rowCount++;
} else {

View File

@ -106,6 +106,8 @@ public class NekoConfig {
public static boolean disableAppBarShadow;
public static boolean mediaPreview;
public static boolean proxyAutoSwitch;
public static String formatLang(String name) {
if (name == null) {
@ -210,6 +212,8 @@ public class NekoConfig {
disableAppBarShadow = preferences.getBoolean("disableAppBarShadow", false);
mediaPreview = preferences.getBoolean("mediaPreview", false);
proxyAutoSwitch = preferences.getBoolean("proxy_auto_switch", false);
}
public static void toggleShowAddToSavedMessages() {
@ -697,4 +701,11 @@ public class NekoConfig {
preferences.edit().putBoolean("mediaPreview",mediaPreview = !mediaPreview).apply();
}
public static void toggleProxyAutoSwitch() {
preferences.edit().putBoolean("proxy_auto_switch",proxyAutoSwitch = !proxyAutoSwitch).apply();
}
}

View File

@ -1,19 +1,117 @@
package tw.nekomimi.nekogram.parts
import android.os.SystemClock
import cn.hutool.core.thread.ThreadUtil
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.telegram.messenger.AndroidUtilities
import org.telegram.messenger.NotificationCenter
import org.telegram.messenger.SharedConfig
import org.telegram.messenger.SharedConfig.ExternalSocks5Proxy
import org.telegram.messenger.UserConfig
import org.telegram.tgnet.ConnectionsManager
import org.telegram.ui.ProxyListActivity
import tw.nekomimi.nekogram.utils.UIUtil
import java.util.concurrent.ExecutorService
import java.util.concurrent.atomic.AtomicBoolean
@JvmOverloads
private suspend fun postCheckSingleProxy(proxyInfo: SharedConfig.ProxyInfo, repeat: Int) {
val lock = AtomicBoolean()
if (proxyInfo is ExternalSocks5Proxy && !proxyInfo.isStarted) {
proxyInfo.start()
delay(233L)
}
var time = -1L
val startAt = SystemClock.elapsedRealtime()
proxyInfo.proxyCheckPingId = ConnectionsManager.getInstance(UserConfig.selectedAccount).checkProxy(proxyInfo.address, proxyInfo.port, proxyInfo.username, proxyInfo.password, proxyInfo.secret) {
time = it
lock.set(true)
}
while (!lock.get() && SystemClock.elapsedRealtime() - startAt < 4000L) delay(100L)
if (!lock.get()) {
proxyInfo.availableCheckTime = SystemClock.elapsedRealtime()
proxyInfo.checking = false
proxyInfo.available = false
proxyInfo.ping = 0
if (proxyInfo is ExternalSocks5Proxy && proxyInfo !== SharedConfig.currentProxy) {
proxyInfo.stop()
}
return
}
if (time == -1L) {
if (repeat > 0) {
postCheckSingleProxy(proxyInfo, repeat - 1)
} else {
proxyInfo.availableCheckTime = SystemClock.elapsedRealtime()
proxyInfo.checking = false
proxyInfo.available = false
proxyInfo.ping = -1L
if (proxyInfo is ExternalSocks5Proxy && proxyInfo !== SharedConfig.currentProxy) {
proxyInfo.stop()
}
}
} else {
proxyInfo.availableCheckTime = SystemClock.elapsedRealtime()
proxyInfo.checking = false
proxyInfo.ping = time
proxyInfo.available = true
if (proxyInfo is ExternalSocks5Proxy && proxyInfo !== SharedConfig.currentProxy) {
proxyInfo.stop()
}
}
}
fun postCheckProxyList() = GlobalScope.launch(Dispatchers.IO) {
SharedConfig.getProxyList().forEach { proxyInfo ->
if (proxyInfo.checking || SystemClock.elapsedRealtime() - proxyInfo.availableCheckTime < 2 * 60 * 1000L) {
return@forEach
}
synchronized(proxyInfo) {
if (proxyInfo.checking || SystemClock.elapsedRealtime() - proxyInfo.availableCheckTime < 2 * 60 * 1000L) {
return@forEach
}
proxyInfo.checking = true
}
runCatching {
postCheckSingleProxy(proxyInfo, 1)
}.onFailure {
proxyInfo.availableCheckTime = SystemClock.elapsedRealtime()
proxyInfo.checking = false
proxyInfo.available = false
proxyInfo.ping = 0
}
}
}
fun ProxyListActivity.checkProxyList(force: Boolean, context: ExecutorService) {
GlobalScope.launch(Dispatchers.IO) {
@ -36,7 +134,11 @@ fun ProxyListActivity.checkProxyList(force: Boolean, context: ExecutorService) {
val lock = AtomicBoolean()
checkSingleProxy(it, if (it is ExternalSocks5Proxy) 3 else 0) {
val startAt = SystemClock.elapsedRealtime()
UIUtil.runOnUIThread { NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.proxyCheckDone, it) }
checkSingleProxy(it, if (it is ExternalSocks5Proxy) 3 else 1) {
AndroidUtilities.runOnUIThread {
@ -48,8 +150,26 @@ fun ProxyListActivity.checkProxyList(force: Boolean, context: ExecutorService) {
}
while (!lock.get()) ThreadUtil.sleep(100L)
while (!lock.get() && SystemClock.elapsedRealtime() - startAt < 4000L) Thread.sleep(100L)
if (!lock.get()) {
it.availableCheckTime = SystemClock.elapsedRealtime()
it.checking = false
it.available = false
it.ping = 0
if (it is ExternalSocks5Proxy && it !== SharedConfig.currentProxy) {
it.stop()
}
AndroidUtilities.runOnUIThread {
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.proxyCheckDone, it)
}
}
}
}

View File

@ -0,0 +1,110 @@
package tw.nekomimi.nekogram.parts
import org.telegram.messenger.SharedConfig
import org.telegram.tgnet.ConnectionsManager
import tw.nekomimi.nekogram.NekoConfig
import tw.nekomimi.nekogram.utils.UIUtil
import java.util.*
object ProxySwitcher {
var currentConnectionState = ConnectionsManager.ConnectionStateWaitingForNetwork
val switchTimer by lazy { Timer("Proxy Switch Timer") }
var currentTask: SwitchTask? = null
fun cancel() {
currentTask = null
switchTimer.purge()
}
fun reschedule() {
cancel()
switchTimer.schedule(SwitchTask().also { currentTask = it }, 3000L)
}
@JvmStatic
fun didReceivedNotification(connectionState: Int) = UIUtil.runOnIoDispatcher run@{
if (!NekoConfig.proxyAutoSwitch) return@run
currentConnectionState = connectionState
if (currentConnectionState == ConnectionsManager.ConnectionStateConnectingToProxy) {
reschedule()
} else {
cancel()
}
}
class SwitchTask : TimerTask() {
override fun run() {
if (this != currentTask) return
if (currentConnectionState != ConnectionsManager.ConnectionStateConnectingToProxy) return
var proxyList = SharedConfig.getProxyList().takeIf { it.size > 1 } ?: return
val current = SharedConfig.currentProxy ?: return
val currIndex = proxyList.indexOf(current)
if (currIndex > 0) {
val proxyListNew = LinkedList<SharedConfig.ProxyInfo>()
proxyListNew.addAll(proxyList.subList(currIndex, proxyList.size))
proxyListNew.addAll(proxyList.subList(0, currIndex + 1))
proxyList = proxyListNew
}
if (proxyList.all { it.availableCheckTime == 0L }) {
if (proxyList.all { !it.checking }) {
repeat(3) { postCheckProxyList() }
}
if (currentConnectionState != ConnectionsManager.ConnectionStateConnectingToProxy) return
SharedConfig.setCurrentProxy(proxyList[0])
reschedule()
return
}
proxyList.forEach {
if (it.availableCheckTime != 0L && !it.available) return@forEach
if (currentConnectionState != ConnectionsManager.ConnectionStateConnectingToProxy) return
SharedConfig.setCurrentProxy(it)
reschedule()
return
}
}
}
}

View File

@ -60,14 +60,13 @@ public class NekoExperimentalSettingsActivity extends BaseFragment {
private int experimentRow;
private int smoothKeyboardRow;
private int mediaPreviewRow;
private int proxyAutoSwitchRow;
private int disableFilteringRow;
private int unlimitedFavedStickersRow;
private int unlimitedPinnedDialogsRow;
private int deleteAccountRow;
private int experiment2Row;
private int shouldNOTTrustMeRow;
private UndoView tooltip;
@Override
@ -224,6 +223,11 @@ public class NekoExperimentalSettingsActivity extends BaseFragment {
tooltip.setInfoText(AndroidUtilities.replaceTags(LocaleController.formatString("BetaWarning", R.string.BetaWarning)));
tooltip.showWithAction(0, UndoView.ACTION_CACHE_WAS_CLEARED, null, null);
}
} else if (position == proxyAutoSwitchRow) {
NekoConfig.toggleProxyAutoSwitch();
if (view instanceof TextCheckCell) {
((TextCheckCell) view).setChecked(NekoConfig.proxyAutoSwitch);
}
}
});
@ -248,6 +252,7 @@ public class NekoExperimentalSettingsActivity extends BaseFragment {
experimentRow = rowCount++;
smoothKeyboardRow = !AndroidUtilities.isTablet() ? rowCount++ : -1;
mediaPreviewRow = rowCount++;
proxyAutoSwitchRow = rowCount++;
disableFilteringRow = rowCount++;
unlimitedFavedStickersRow = rowCount++;
unlimitedPinnedDialogsRow = rowCount++;
@ -389,8 +394,10 @@ public class NekoExperimentalSettingsActivity extends BaseFragment {
textCell.setTextAndCheck(LocaleController.getString("DebugMenuEnableSmoothKeyboard", R.string.DebugMenuEnableSmoothKeyboard), SharedConfig.smoothKeyboard, true);
} else if (position == unlimitedPinnedDialogsRow) {
textCell.setTextAndValueAndCheck(LocaleController.getString("UnlimitedPinnedDialogs", R.string.UnlimitedPinnedDialogs), LocaleController.getString("UnlimitedPinnedDialogsAbout", R.string.UnlimitedPinnedDialogsAbout), NekoConfig.unlimitedPinnedDialogs, true, deleteAccountRow != -1);
} else if (position == mediaPreviewRow) {
} else if (position == mediaPreviewRow) {
textCell.setTextAndCheck(LocaleController.getString("MediaPreview", R.string.MediaPreview), NekoConfig.mediaPreview, true);
} else if (position == proxyAutoSwitchRow) {
textCell.setTextAndCheck(LocaleController.getString("ProxyAutoSwitch", R.string.ProxyAutoSwitch), NekoConfig.proxyAutoSwitch, true);
}
break;
}
@ -453,13 +460,10 @@ public class NekoExperimentalSettingsActivity extends BaseFragment {
return 1;
} else if (position == deleteAccountRow) {
return 2;
} else if (position == unlimitedFavedStickersRow || position == disableFilteringRow ||
position == smoothKeyboardRow || position == unlimitedPinnedDialogsRow || position == mediaPreviewRow) {
return 3;
} else if (position == experimentRow) {
return 4;
}
return 2;
return 3;
}
}
}

View File

@ -21,14 +21,14 @@ object HttpUtil {
@JvmField
val okHttpClient = OkHttpClient().newBuilder()
.dns(DnsFactory)
.connectTimeout(3, TimeUnit.SECONDS)
.readTimeout(3, TimeUnit.SECONDS)
.connectTimeout(2, TimeUnit.SECONDS)
.readTimeout(2, TimeUnit.SECONDS)
.build()
val okHttpClientNoDoh = OkHttpClient()
.newBuilder()
.connectTimeout(3, TimeUnit.SECONDS)
.readTimeout(3, TimeUnit.SECONDS)
.connectTimeout(2, TimeUnit.SECONDS)
.readTimeout(2, TimeUnit.SECONDS)
.build()
@JvmStatic

View File

@ -51,7 +51,6 @@
<string name="PrivacyNotice2fa">تم اكتشاف أنك لم تقم بإيقاف تشغيل إعدادات \"المكالمات من نظير لنظيرp2p\"، قد يتسبب في العثور على هويتك الحقيقية للقرصنة التي تسيطر عليها الحكومة، يرجى إيقافها!</string>
<string name="ApplySuggestion">حسنًا، قم بتطبيقه</string>
<string name="DoNotRemindAgain">لا تذكرني مرة أخرى</string>
<string name="InstantViewTransWithWeb">لا يمكن ترجمة InstantView مع مترجم الويب</string>
<string name="RemoveTitleEmoji">إزالة الرموز التعبيرية من العناوين</string>
<string name="NekoXProxy">خادم NekoX العام</string>
<string name="PublicPrefix">عامة</string>

View File

@ -51,7 +51,6 @@
<string name="PrivacyNotice2fa">Es wurde festgestellt, dass Du kein Passwort festgelegt hast, was dazu führen kann, dass staatlich kontrollierte Hacker Deine wahre Identität ermitteln können. Bitte setze eines!</string>
<string name="ApplySuggestion">OK, anwenden</string>
<string name="DoNotRemindAgain">Nicht mehr erinnern</string>
<string name="InstantViewTransWithWeb">InstantView kann nicht mit dem Web-Übersetzer übersetzt werden</string>
<string name="RemoveTitleEmoji">Emoji im Titel entfernen</string>
<string name="NekoXProxy">Öffentlicher NekoX-Proxy</string>
<string name="PublicPrefix">Öffentlich</string>

View File

@ -51,7 +51,6 @@
<string name="PrivacyNotice2fa">Se detecta que no ha establecido una contraseña, lo que puede causar que los hackers controlados por el gobierno encuentren su verdadera identidad, ¡por favor configure una!</string>
<string name="ApplySuggestion">OK, aplícalo</string>
<string name="DoNotRemindAgain">No volver a recordar</string>
<string name="InstantViewTransWithWeb">No se puede traducir InstantView con el traductor web</string>
<string name="RemoveTitleEmoji">Eliminar emoji en el título</string>
<string name="NekoXProxy">Proxy público de NekoX</string>
<string name="PublicPrefix">Público</string>

View File

@ -51,7 +51,6 @@
<string name="PrivacyNotice2fa">تشخیص داده می شود که رمز عبوری تنظیم نکرده اید ، و این ممکن است باعث شود هکرهای تحت کنترل دولت هویت واقعی شما را پیدا کنند ، لطفاً آنرا تعیین کنید</string>
<string name="ApplySuggestion">قبول،اعمال کن</string>
<string name="DoNotRemindAgain">دیگر یادآوری نشود</string>
<string name="InstantViewTransWithWeb">ترجمه InstantView با مترجم وب امکان پذیر نیست</string>
<string name="RemoveTitleEmoji">حذف ایموجی کنار اسم Nekogram x</string>
<string name="NekoXProxy">پروکسی عمومی NekoX</string>
<string name="PublicPrefix">عمومی</string>

View File

@ -51,7 +51,6 @@
<string name="PrivacyNotice2fa">מתגלה שלא הגדרת סיסמה, מה שעלול לגרום להאקרים שבשליטת הממשלה למצוא את זהותך האמיתית, אנא הגדר סיסמה!</string>
<string name="ApplySuggestion">אוקיי, החל אותו</string>
<string name="DoNotRemindAgain">אל תזכיר שוב</string>
<string name="InstantViewTransWithWeb">לא ניתן לתרגם את InstantView באמצעות מתרגם לאינטרנט</string>
<string name="RemoveTitleEmoji">הסר אמוג\'י בכותרת</string>
<string name="NekoXProxy">פרוקסי ציבור NekoX</string>
<string name="PublicPrefix">ציבורי</string>

View File

@ -1,170 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="CustomApi">Egyéni API</string>
<string name="UseCustomApiNotice">Jelentkezzen be az egyéni alkalmazás segítségével, ha nem tud regisztrálni vagy bejelentkezni, ez segíthet.\n\nMegjegyzés: Az fcm nem fog működni, ha a kiadási verziót használja.</string>
<string name="CustomApiNo">Ne használjon egyedi API-t</string>
<string name="CustomApiOfficial">Android távirat</string>
<string name="CustomApiTGX">Telegram Android X</string>
<string name="CustomApiInput">Kézi bevitel</string>
<string name="CheckUpdate">Frissítés ellenőrzése</string>
<string name="SwitchVersion">Váltás a verzióra</string>
<string name="NoUpdate">Nem található frissítés</string>
<string name="UpdateAvailable">Új frissítés elérhető</string>
<string name="UpdateUpdate">frissítés</string>
<string name="UpdateLater">Majd később</string>
<string name="DownloadFailed">Sikertelen letöltés</string>
<string name="Install">Telepítés</string>
<string name="Ignore">Figyelmen kívül hagyni</string>
<string name="UpdateDownloaded">Nemrég letöltött egy frissítést.</string>
<string name="LinkedGroupChat">Kapcsolt csoport</string>
<string name="LinkedChannelChat">Linked Channel</string>
<string name="DevModeTitle">** Távszámláját betilthatjuk **</string>
<string name="DevModeNotice">Nem vagyunk felelősek a fejlesztői szolgáltatások nem megfelelő használatáért.</string>
<string name="TapToDisable">Érintse meg a letiltáshoz. Nem kell ezekre.</string>
<string name="PlaceHolder">Helyőrző - kérjük, tiltsa le</string>
<string name="CustomBackend">Egyéni háttér</string>
<string name="CustomBackendNotice">Ezt a funkciót csak szakértő felhasználók számára biztosítják, ha nem tudják, hogy mit jelentenek a következő lehetőségek, akkor hagyja figyelmen kívül.</string>
<string name="CustomBackendProduction">Hivatalos Gyártási DataCenter</string>
<string name="CustomBackendTestDC">Hivatalos teszt-adatközpont</string>
<string name="CustomBackendIpv4">IPv4 cím</string>
<string name="CustomBackendIpv6">IPv6 cím</string>
<string name="CustomBackendLayer">Réteg</string>
<string name="CustomBackendPublicKey">Nyilvános kulcs</string>
<string name="CustomBackendFingerprint">Kulcs ujjlenyomata</string>
<string name="CachePath">Gyorsítótár könyvtár</string>
<string name="AllowFlashCall">Flash hívás engedélyezése</string>
<string name="ChangeTranslateProvider">Cserélje ki a szolgáltatót</string>
<string name="ProviderYandexTranslate">Yandex.Translate</string>
<string name="GoogleCloudTransKey">Google Cloud Translate kulcs</string>
<string name="GoogleCloudTransKeyNotice">Ha beállít egy Google Cloud Trans kulcsot, akkor a felhő fordítási API-t hívja meg, és nem fordít hamis űrlapot a webes verzióhoz, amikor fordítja (gyorsabb, stabil és forgalmat takarít meg).</string>
<string name="TransToLang">Fordítási célnyelv</string>
<string name="TransInputToLang">Fordítási beviteli célnyelv</string>
<string name="More">Több</string>
<string name="NekoXUpdatesChannel">A NekoX frissíti a csatornát</string>
<string name="ShowIdAndDc">ID / DC megjelenítése a profilban</string>
<string name="UseDefaultTheme">Alapértelmezett téma használata *</string>
<string name="NightMode">Éjszakai mód</string>
<string name="PrivacyNotice">Adatvédelmi figyelmeztetés</string>
<string name="PrivacyNoticePhoneVisible">Megállapítottuk, hogy mobiltelefonszámát bárki láthatja, ami miatt a kormány által ellenőrzött hackerek megtalálhatják az Ön igazi személyazonosságát, kérjük kapcsolja ki!</string>
<string name="PrivacyNoticeAddByPhone">Megállapítást nyert, hogy nem van kikapcsolva az \"Engedélyezzen, hogy telefonszámon keressek\" beállítást, amely miatt a kormány által ellenőrzött hackerek megtalálhatják az Ön igazi személyazonosságát, kérjük, kapcsolja ki!</string>
<string name="PrivacyNoticeP2p">Megállapította, hogy nem kapcsolta ki az \"Engedélyezi a P2p hívásokat\" beállítást, amely miatt a kormány által ellenőrzött hackerek megtalálhatják az Ön igazi személyazonosságát, kérjük kapcsolja ki!</string>
<string name="PrivacyNotice2fa">Megállapította, hogy még nem állított be jelszót, ami miatt a kormány által ellenőrzött hackerek megtalálhatják az Ön valódi személyazonosságát, kérjük, állítsa be!</string>
<string name="ApplySuggestion">OK, alkalmazza</string>
<string name="DoNotRemindAgain">Ne emlékeztesse újra</string>
<string name="InstantViewTransWithWeb">Az InstantView nem fordítható le webes fordítóval</string>
<string name="RemoveTitleEmoji">Távolítsa el a hangulatjeleket a címből</string>
<string name="NekoXProxy">NekoX nyilvános proxy</string>
<string name="PublicPrefix">Nyilvános</string>
<string name="DisableChatAction">Ne küldje el a bemeneti állapotomat</string>
<string name="FakeScreenshot">Képzeld el a képernyőképet</string>
<string name="Import">import</string>
<string name="FilterNameUsers">felhasználók</string>
<string name="FilterNameUsersDescription">Csak a privát csevegőktől származó üzenetek</string>
<string name="FilterNameContacts">Kapcsolatok</string>
<string name="FilterNameContactsDescription">Csak a mentett felhasználók üzenetei</string>
<string name="FilterNameGroups">csoportok</string>
<string name="FilterNameGroupsDescription">Csak a csoportbeszélgetések üzenetei</string>
<string name="FilterNameChannels">Csatornák</string>
<string name="FilterNameChannelsDescription">Csak a csatornáktól érkező üzenetek</string>
<string name="FilterNameBots">Botok</string>
<string name="FilterNameBotsDescription">Csak a robotok üzenetei</string>
<string name="FilterNameUnmuted">újra megszólal</string>
<string name="FilterNameUnmutedDescription">Csak a némítás nélküli beszélgetések üzenetei</string>
<string name="FilterNameUnread2">Nem olvasott</string>
<string name="FilterNameUnreadDescription">Csak olvasatlan üzenetek</string>
<string name="FilterNameUnmutedAndUnread">Némítva &amp; Olvasatlan</string>
<string name="FilterNameUnmutedAndUnreadDescription">Csak olvasatlan üzenetek a némítás nélküli csevegésekből</string>
<string name="IgnoreMutedCount">Figyelmen kívül hagyja a néma olvasatlan számot a mappák lapon</string>
<string name="DialogsSettings">A párbeszédablakok beállításai</string>
<string name="SortMenu">Párbeszédrendezési beállítások</string>
<string name="SortByUnread">Rendezés olvasatlanul</string>
<string name="SortByUnmuted">Rendezés némítás nélkül</string>
<string name="SortByUser">Rendezés felhasználó szerint</string>
<string name="SortByContacts">Rendezés névjegyek szerint</string>
<string name="NekoXPushService">NekoX push szolgáltatás</string>
<string name="EnablePushAlert">Kérjük, engedélyezze a \"NekoX Push Service\" szolgáltatást</string>
<string name="DisablePushAlert">Kérjük, tiltsa le a \"NekoX Push Service\" szolgáltatást</string>
<string name="DisableUndo">Kapcsolja ki a Visszavonást</string>
<string name="DisableSystemAccount">A rendszerfiók letiltása</string>
<string name="FilterMenu">A párbeszédablakok szűrőmenüje</string>
<string name="DisableProxyWhenVpnEnabled">Proxy letiltása, ha a VPN engedélyezve van</string>
<string name="UseProxyItem">Használja az oldalsáv proxy elemét a gomb helyett</string>
<string name="HideProxyByDefault">Proxybeállítások elrejtése alapértelmezés szerint</string>
<string name="SkipOpenLinkConfirm">Ugrás a nyitott link megerősítéséhez</string>
<string name="DeleteAllInChat">Az összes törlése a csevegésben</string>
<string name="DeleteAllInChatAlert">Figyelem! Ez ** a chat összes üzenetét ** törli ** az összes ** résztvevő számára.</string>
<string name="UnblockAll">Összes feloldása</string>
<string name="UnblockAllWarn">Biztos benne, hogy feloldja ** az összes felhasználót és a robotot **?</string>
<string name="BlockedListEmpty">Nem blokkoltál senkit :)</string>
<string name="ProxyTypeVmess">Vmess Proxy</string>
<string name="AddProxySocks5">Adja hozzá a Socks5 Proxy alkalmazást</string>
<string name="AddProxyTelegram">Adja hozzá az MTProto Proxy alkalmazást</string>
<string name="AddProxyVmess">Adja hozzá a Vmess Proxy-t</string>
<string name="AddProxySS">Adjon hozzá Shadowsocks Proxy-t</string>
<string name="AddProxySSR">Adjon hozzá ShadowsocksR Proxy-t</string>
<string name="AddProxyRB">Adja hozzá a RelayBaton Proxy alkalmazást</string>
<string name="SSPluginConflictingName">Több bővítmény használja ezt az azonosítót: %s.</string>
<string name="EditProxy">Proxy szerkesztése</string>
<string name="ShareProxy">Proxy megosztása</string>
<string name="ProxyDelete">Proxy törlése</string>
<string name="ProxyInfoVmess">Vmess proxybeállítások</string>
<string name="VmessUserId">Felhasználói azonosító</string>
<string name="VmessAlterId">Alter Id</string>
<string name="VmessSecurity">Biztonság</string>
<string name="VmessNetwork">Hálózat</string>
<string name="VmessHeadType">Fej típusa</string>
<string name="VmessRequestHost">Host / QUIC biztonság kérése</string>
<string name="VmessPath">Útvonal / QUIC kulcs</string>
<string name="VmessTls">Használja a TLS-t</string>
<string name="ProxyInfoSS">Shadowsocks proxybeállítások</string>
<string name="SSPassword">Jelszó</string>
<string name="SSMethod">Titkosítási módszer</string>
<string name="SSPlugin">Csatlakoztat</string>
<string name="SSPluginOpts">Beépülő modul konfigurációja</string>
<string name="ProxyInfoSSR">ShadowsocksR proxybeállítások</string>
<string name="SSRProtocol">Jegyzőkönyv</string>
<string name="SSRProtocolParams">Protokollparaméterek</string>
<string name="SSRObfs">Obfs</string>
<string name="SSRObfsParam">Obfs Param</string>
<string name="ProxyInfoRB">RelayBaton proxybeállítások</string>
<string name="ESNI">Titkosított SNI</string>
<string name="ProxyRemarks">Megjegyzések</string>
<string name="RetestPing">Vizsgálja meg újra az összes kiszolgálót</string>
<string name="ReorderByPing">Szerverek átrendezése ping segítségével</string>
<string name="ExportProxies">Kiszolgálók exportálása fájlba</string>
<string name="ImportProxies">Kiszolgálók importálása a fájlból</string>
<string name="ImportProxyList">Proxykiszolgálók importálása</string>
<string name="ProxySubscription">Proxy előfizetés</string>
<string name="ProxySubDetails">Előfizetés részletei</string>
<string name="SubscriptionUrls">urls</string>
<string name="SubscriptionUpdating">Az előfizetés frissítése</string>
<string name="SubscriptionDelete">Az előfizetés törlése</string>
<string name="ExportStickers">Export matricák</string>
<string name="ImportStickers">Matricák importálása a fájlból</string>
<string name="ImportStickersList">Import matricák</string>
<string name="StickerSets">Matricakészletek</string>
<string name="InvalidStickersFile">Érvénytelen matricafájl: </string>
<string name="InvalidProxyFile">Érvénytelen proxy listafájl: </string>
<string name="ImportedProxies">Importált proxyszerverek: </string>
<string name="ErrorsInImport">Importálási hibák: </string>
<string name="NoProxy">Még nem adott meg proxykiszolgálót.</string>
<string name="DeleteAllServer">Törölje az összes kiszolgálót</string>
<string name="DeleteUnavailableServer">Törölje a nem elérhető kiszolgálókat</string>
<string name="DeleteAllServerConfirm">Biztosan törli ** az összes kiszolgálót **?</string>
<string name="DeleteUnavailableServerConfirm">Biztosan törli a nem elérhető kiszolgálókat **?</string>
<string name="MinApi21Required">Sajnálom, de legalább Android 5-re (API21) van szükséged.</string>
<string name="MiniVersionAlert">Sajnos a mini verzió nem támogatja az ilyen típusú proxyt, kérjük, váltson a verzióra a beállításokban.</string>
<string name="ImportProxyFromClipboard">Importálás a vágólapra</string>
<string name="BrokenLink">Ismeretlen / megszakadt link</string>
<string name="ShareQRCode">QR-kód</string>
<string name="ScanQRCode">QR kód beolvasása</string>
<string name="NoQrFound">Nem található QR-kód</string>
<string name="EnableDeveloperMode">Fejlesztői mód engedélyezése</string>
<string name="DisableDeveloperMode">A fejlesztői mód letiltása</string>
<string name="DeveloperSettings">Fejlesztői beállítások</string>
<string name="LoginSettings">Bejelentkezés beállítások</string>
<string name="NekoXFaq">NekoX GYIK</string>
<string name="TransSite">Fordítóplatform</string>
<string name="NekoTrans">Nekogram fordítása</string>
<string name="NekoXTrans">Fordítás NekoX</string>
</resources>
<resources></resources>

View File

@ -51,7 +51,6 @@
<string name="PrivacyNotice2fa">Terdeteksi bahwa anda belum menetapkan kata sandi, yang dapat menyebabkan peretas yang dimiliki pemerintah menemukan identitas anda yang sebenarnya, harap setel!</string>
<string name="ApplySuggestion">Oke, Terapkan</string>
<string name="DoNotRemindAgain">Jangan Ingatkan lagi</string>
<string name="InstantViewTransWithWeb">Tidak dapat menerjemahkan InstantView menggunakan penerjemah web</string>
<string name="RemoveTitleEmoji">Hapus emoji dari judul Nekogram X</string>
<string name="NekoXProxy">NekoX Publik Proxy</string>
<string name="PublicPrefix">Publik</string>

View File

@ -51,7 +51,6 @@
<string name="PrivacyNotice2fa">パスワードが設定されていないことが検出されました。これにより、政府の管理下にあるハッカーがあなたの本当の身元を見つける可能性があります。パスワードを設定してください。</string>
<string name="ApplySuggestion">わかりました。 適用します</string>
<string name="DoNotRemindAgain">今後表示しない</string>
<string name="InstantViewTransWithWeb">ウェブ翻訳者でInstantViewを翻訳できません</string>
<string name="RemoveTitleEmoji">タイトルの絵文字を削除</string>
<string name="NekoXProxy">NekoXパブリックプロキシ</string>
<string name="PublicPrefix">パブリック</string>

View File

@ -51,7 +51,6 @@
<string name="PrivacyNotice2fa">비밀번호 설정을 하지 않았습니다. 정부에서 관리하는 해커가 신원을 확인 할 수 있습니다. 비밀번호를 설정하십시오!</string>
<string name="ApplySuggestion">예. 등록합니다.</string>
<string name="DoNotRemindAgain">다시 표시하지 않기</string>
<string name="InstantViewTransWithWeb">웹 번역기로 InstantView를 번역 할 수 없습니다</string>
<string name="RemoveTitleEmoji">제목에서 이모티콘 제거</string>
<string name="NekoXProxy">NekoX 공개 프록시</string>
<string name="PublicPrefix">공개</string>

View File

@ -51,7 +51,6 @@
<string name="PrivacyNotice2fa">Foi detectado que você não definiu uma senha, o que pode fazer com que os hackers controlados pelo governo encontrem sua verdadeira identidade, por favor, defina uma!</string>
<string name="ApplySuggestion">OK, Aplicar</string>
<string name="DoNotRemindAgain">Não lembre novamente</string>
<string name="InstantViewTransWithWeb">Não é possível traduzir InstantView com o tradutor web</string>
<string name="RemoveTitleEmoji">Remover emoji no título</string>
<string name="NekoXProxy">Proxy Público do NekoX</string>
<string name="PublicPrefix">Público</string>

View File

@ -51,7 +51,6 @@
<string name="PrivacyNotice2fa">Для повышения конфиденциальности рекомендуем включить двухфакторную аутентификацию.</string>
<string name="ApplySuggestion">Ок, сделаем это!</string>
<string name="DoNotRemindAgain">Больше не напоминать</string>
<string name="InstantViewTransWithWeb">Невозможно перевести InstantView с веб-переводчиком</string>
<string name="RemoveTitleEmoji">Убрать эмодзи из шапки</string>
<string name="NekoXProxy">Список прокси от NekoX</string>
<string name="PublicPrefix">Из списка</string>

View File

@ -51,7 +51,6 @@
<string name="PrivacyNotice2fa">Devlet kontrolündeki bilgisayar korsanlarının gerçek kimliğinizi bulmasına neden olabilecek bir şifre ayarlamadığınız tespit edildi, lütfen bir tane belirleyin!</string>
<string name="ApplySuggestion">Tamam, uygula</string>
<string name="DoNotRemindAgain">Bir daha hatırlatma</string>
<string name="InstantViewTransWithWeb">InstantView web çevirmeni ile çevrilemiyor</string>
<string name="RemoveTitleEmoji">Başlıktaki emojiyi (😶) kaldırın</string>
<string name="NekoXProxy">NekoX Genel Proxy</string>
<string name="PublicPrefix">Genel</string>

View File

@ -51,7 +51,6 @@
<string name="PrivacyNotice2fa">Виявлено, що ви не встановили пароль, через що хакери під контролем уряду можуть знайти справжню особу, будь ласка, встановіть його!</string>
<string name="ApplySuggestion">Добре, застосувати</string>
<string name="DoNotRemindAgain">Не нагадувати більше</string>
<string name="InstantViewTransWithWeb">Неможливо перекласти InstantView з web translator</string>
<string name="RemoveTitleEmoji">Видаляти смайли в назві</string>
<string name="NekoXProxy">Публічний проксі NekoX</string>
<string name="PublicPrefix">Загальнодоступна</string>

View File

@ -16,6 +16,7 @@
<string name="Install">安装</string>
<string name="Ignore">忽略</string>
<string name="UpdateDownloaded">一个更新刚刚下载完成.</string>
<string name="ProxyAutoSwitch">代理自动切换</string>
<string name="LinkedGroupChat">链接的群组</string>
<string name="LinkedChannelChat">链接的频道</string>
<string name="DevModeTitle">**您的电报账号可能被封禁**</string>
@ -51,7 +52,6 @@
<string name="PrivacyNotice2fa">检测到您没有设置密码,这可能会导致政府控制的黑客找到您的真实身份,请设置一个!</string>
<string name="ApplySuggestion">应用</string>
<string name="DoNotRemindAgain">不再提醒</string>
<string name="InstantViewTransWithWeb">无法使用网页翻译器翻译 InstantView</string>
<string name="RemoveTitleEmoji">移除标题中的表情</string>
<string name="NekoXProxy">NekoX 公共代理</string>
<string name="PublicPrefix">公共</string>

View File

@ -51,7 +51,6 @@
<string name="PrivacyNotice2fa">檢測到您尚未設置密碼,這可能導致政府控制的黑客找到您的真實身份,請設置一個!</string>
<string name="ApplySuggestion">應用</string>
<string name="DoNotRemindAgain">不再提醒</string>
<string name="InstantViewTransWithWeb">無法使用網絡翻譯器翻譯InstantView</string>
<string name="RemoveTitleEmoji">移除標題中的表情</string>
<string name="NekoXProxy">NekoX 公共代理</string>
<string name="PublicPrefix">公共</string>

View File

@ -51,7 +51,6 @@
<string name="PrivacyNotice2fa">檢測到您尚未設置密碼,這可能導致政府控制的黑客找到您的真實身份,請設置一個!</string>
<string name="ApplySuggestion">套用</string>
<string name="DoNotRemindAgain">不再提醒</string>
<string name="InstantViewTransWithWeb">無法使用網絡翻譯器翻譯InstantView</string>
<string name="RemoveTitleEmoji">移除標題中的表情</string>
<string name="NekoXProxy">NekoX 公共代理</string>
<string name="PublicPrefix">公共</string>

View File

@ -20,6 +20,7 @@
<string name="Install">Install</string>
<string name="Ignore">Ignore</string>
<string name="UpdateDownloaded">An update has just been downloaded.</string>
<string name="ProxyAutoSwitch">Proxy Auto Switch</string>
<string name="LinkedGroupChat">Linked Group</string>
<string name="LinkedChannelChat">Linked Channel</string>

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists