NekoX/TMessagesProj/src/main/java/org/telegram/messenger/ProxyRotationController.java

129 lines
5.5 KiB
Java

package org.telegram.messenger;
import android.content.SharedPreferences;
import android.os.SystemClock;
import org.telegram.tgnet.ConnectionsManager;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class ProxyRotationController implements NotificationCenter.NotificationCenterDelegate {
private final static ProxyRotationController INSTANCE = new ProxyRotationController();
public final static int DEFAULT_TIMEOUT_INDEX = 1;
public final static List<Integer> ROTATION_TIMEOUTS = Arrays.asList(
5, 10, 15, 30, 60
);
private boolean isCurrentlyChecking;
private Runnable checkProxyAndSwitchRunnable = () -> {
isCurrentlyChecking = true;
int currentAccount = UserConfig.selectedAccount;
boolean startedCheck = false;
for (int i = 0; i < SharedConfig.proxyList.size(); i++) {
SharedConfig.ProxyInfo proxyInfo = SharedConfig.proxyList.get(i);
if (proxyInfo.checking || SystemClock.elapsedRealtime() - proxyInfo.availableCheckTime < 2 * 60 * 1000) {
continue;
}
startedCheck = true;
proxyInfo.checking = true;
proxyInfo.proxyCheckPingId = ConnectionsManager.getInstance(currentAccount).checkProxy(proxyInfo.address, proxyInfo.port, proxyInfo.username, proxyInfo.password, proxyInfo.secret, time -> AndroidUtilities.runOnUIThread(() -> {
proxyInfo.availableCheckTime = SystemClock.elapsedRealtime();
proxyInfo.checking = false;
if (time == -1) {
proxyInfo.available = false;
proxyInfo.ping = 0;
} else {
proxyInfo.ping = time;
proxyInfo.available = true;
}
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.proxyCheckDone, proxyInfo);
}));
}
if (!startedCheck) {
isCurrentlyChecking = false;
switchToAvailable();
}
};
public static void init() {
INSTANCE.initInternal();
}
@SuppressWarnings("ComparatorCombinators")
private void switchToAvailable() {
isCurrentlyChecking = false;
if (!SharedConfig.proxyRotationEnabled) {
return;
}
List<SharedConfig.ProxyInfo> sortedList = new ArrayList<>(SharedConfig.proxyList);
Collections.sort(sortedList, (o1, o2) -> Long.compare(o1.ping, o2.ping));
for (SharedConfig.ProxyInfo info : sortedList) {
if (info == SharedConfig.currentProxy || info.checking || !info.available) {
continue;
}
SharedPreferences.Editor editor = MessagesController.getGlobalMainSettings().edit();
editor.putString("proxy_ip", info.address);
editor.putString("proxy_pass", info.password);
editor.putString("proxy_user", info.username);
editor.putInt("proxy_port", info.port);
editor.putString("proxy_secret", info.secret);
editor.putBoolean("proxy_enabled", true);
if (!info.secret.isEmpty()) {
editor.putBoolean("proxy_enabled_calls", false);
}
editor.apply();
SharedConfig.currentProxy = info;
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.proxySettingsChanged);
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.proxyChangedByRotation);
ConnectionsManager.setProxySettings(true, SharedConfig.currentProxy.address, SharedConfig.currentProxy.port, SharedConfig.currentProxy.username, SharedConfig.currentProxy.password, SharedConfig.currentProxy.secret);
break;
}
}
private void initInternal() {
for (int i = 0; i < UserConfig.MAX_ACCOUNT_COUNT; i++) {
NotificationCenter.getInstance(i).addObserver(this, NotificationCenter.didUpdateConnectionState);
}
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.proxyCheckDone);
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.proxySettingsChanged);
}
@Override
public void didReceivedNotification(int id, int account, Object... args) {
if (id == NotificationCenter.proxyCheckDone) {
if (!SharedConfig.isProxyEnabled() || !SharedConfig.proxyRotationEnabled || SharedConfig.proxyList.size() <= 1 || !isCurrentlyChecking) {
return;
}
switchToAvailable();
} else if (id == NotificationCenter.proxySettingsChanged) {
AndroidUtilities.cancelRunOnUIThread(checkProxyAndSwitchRunnable);
} else if (id == NotificationCenter.didUpdateConnectionState && account == UserConfig.selectedAccount) {
if (!SharedConfig.isProxyEnabled() && !SharedConfig.proxyRotationEnabled || SharedConfig.proxyList.size() <= 1) {
return;
}
int state = ConnectionsManager.getInstance(account).getConnectionState();
if (state == ConnectionsManager.ConnectionStateConnectingToProxy) {
if (!isCurrentlyChecking) {
AndroidUtilities.runOnUIThread(checkProxyAndSwitchRunnable, ROTATION_TIMEOUTS.get(SharedConfig.proxyRotationTimeout) * 1000L);
}
} else {
AndroidUtilities.cancelRunOnUIThread(checkProxyAndSwitchRunnable);
}
}
}
}