Keep userbots in group
This commit is contained in:
parent
e0a862bf40
commit
52019d505a
@ -9,18 +9,18 @@
|
|||||||
<mountPoint id="157" />
|
<mountPoint id="157" />
|
||||||
</mountPoints>
|
</mountPoints>
|
||||||
<entries>
|
<entries>
|
||||||
<dirEntry mountPoint="157" file="/home/ubuntu/IdeaProjects/TransferBot/target/lib" entryMode="subdir" subDirectory="lib" />
|
|
||||||
<fileEntry mountPoint="157" file="/home/ubuntu/IdeaProjects/TransferBot/target/TransferBot-1.0-SNAPSHOT.jar" />
|
<fileEntry mountPoint="157" file="/home/ubuntu/IdeaProjects/TransferBot/target/TransferBot-1.0-SNAPSHOT.jar" />
|
||||||
</entries>
|
</entries>
|
||||||
</files>
|
</files>
|
||||||
<launchers>
|
<launchers>
|
||||||
<launcher name="transferbot" id="58">
|
<launcher name="transferbot" id="58">
|
||||||
<executable name="transferbot" executableDir="." executableMode="gui" />
|
<executable name="transferbot" executableDir="." executableMode="gui" />
|
||||||
<java mainClass="it.cavallium/it.cavallium.App" mainMode="module">
|
<java mainClass="it.cavallium.Launcher">
|
||||||
<modulePath>
|
<classPath>
|
||||||
<directory location="classes" failOnError="false" />
|
<archive location="TransferBot-1.0-SNAPSHOT.jar" failOnError="false" />
|
||||||
|
</classPath>
|
||||||
|
<modulePath>
|
||||||
<archive location="TransferBot-1.0-SNAPSHOT.jar" failOnError="false" />
|
<archive location="TransferBot-1.0-SNAPSHOT.jar" failOnError="false" />
|
||||||
<directory location="lib" failOnError="false" />
|
|
||||||
</modulePath>
|
</modulePath>
|
||||||
</java>
|
</java>
|
||||||
</launcher>
|
</launcher>
|
||||||
|
@ -15,12 +15,17 @@ import it.tdlight.jni.TdApi.UpdateAuthorizationState;
|
|||||||
import it.tdlight.jni.TdApi.UpdateNewChat;
|
import it.tdlight.jni.TdApi.UpdateNewChat;
|
||||||
import it.tdlight.jni.TdApi.UpdateSupergroup;
|
import it.tdlight.jni.TdApi.UpdateSupergroup;
|
||||||
import it.tdlight.jni.TdApi.UpdateSupergroupFullInfo;
|
import it.tdlight.jni.TdApi.UpdateSupergroupFullInfo;
|
||||||
|
import it.tdlight.jni.TdApi.User;
|
||||||
import it.tdlight.tdlibsession.td.TdResult;
|
import it.tdlight.tdlibsession.td.TdResult;
|
||||||
import it.tdlight.tdlibsession.td.easy.AsyncTdEasy;
|
import it.tdlight.tdlibsession.td.easy.AsyncTdEasy;
|
||||||
|
import it.tdlight.utils.MonoUtils;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.StringJoiner;
|
import java.util.StringJoiner;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import reactor.core.publisher.EmitterProcessor;
|
import reactor.core.publisher.EmitterProcessor;
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
@ -32,6 +37,7 @@ public class TransferClient {
|
|||||||
|
|
||||||
private final String alias;
|
private final String alias;
|
||||||
private final AsyncTdEasy client;
|
private final AsyncTdEasy client;
|
||||||
|
private final AtomicReference<User> clientUser = new AtomicReference<>(null);
|
||||||
private final ConcurrentHashMap<Integer, Supergroup> supergroupInfos = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<Integer, Supergroup> supergroupInfos = new ConcurrentHashMap<>();
|
||||||
private final ConcurrentHashMap<Integer, SupergroupFullInfo> supergroupFullInfos = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<Integer, SupergroupFullInfo> supergroupFullInfos = new ConcurrentHashMap<>();
|
||||||
private final ConcurrentHashMap<Long, Chat> chats = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<Long, Chat> chats = new ConcurrentHashMap<>();
|
||||||
@ -51,6 +57,10 @@ public class TransferClient {
|
|||||||
.subscribe();
|
.subscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public User getClientUser() {
|
||||||
|
return Objects.requireNonNull(clientUser.get(), "Userbot details not already received!");
|
||||||
|
}
|
||||||
|
|
||||||
private Mono<Void> onUpdate(Update update) {
|
private Mono<Void> onUpdate(Update update) {
|
||||||
switch (update.getConstructor()) {
|
switch (update.getConstructor()) {
|
||||||
case UpdateSupergroup.CONSTRUCTOR:
|
case UpdateSupergroup.CONSTRUCTOR:
|
||||||
@ -71,7 +81,15 @@ public class TransferClient {
|
|||||||
private Mono<Void> onUpdateAuthorizationState(AuthorizationState authorizationState) {
|
private Mono<Void> onUpdateAuthorizationState(AuthorizationState authorizationState) {
|
||||||
switch (authorizationState.getConstructor()) {
|
switch (authorizationState.getConstructor()) {
|
||||||
case AuthorizationStateReady.CONSTRUCTOR:
|
case AuthorizationStateReady.CONSTRUCTOR:
|
||||||
return TransferUtils.getAllHomeChats(this).flatMap(this::onChat).then();
|
return TransferUtils
|
||||||
|
.getAllHomeChats(this)
|
||||||
|
.timeout(Duration.ofMinutes(2))
|
||||||
|
.flatMap(this::onChat)
|
||||||
|
.then(client.<User>send(new TdApi.GetMe())
|
||||||
|
.flatMap(MonoUtils::orElseThrow)
|
||||||
|
.timeout(Duration.ofSeconds(30))
|
||||||
|
.doOnSuccess(this.clientUser::set))
|
||||||
|
.then();
|
||||||
default:
|
default:
|
||||||
return Mono.empty();
|
return Mono.empty();
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import com.google.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat;
|
|||||||
import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
|
import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
|
||||||
import com.hazelcast.cp.internal.util.Tuple2;
|
import com.hazelcast.cp.internal.util.Tuple2;
|
||||||
import com.hazelcast.cp.internal.util.Tuple3;
|
import com.hazelcast.cp.internal.util.Tuple3;
|
||||||
|
import io.vertx.core.impl.ConcurrentHashSet;
|
||||||
import it.tdlight.jni.TdApi;
|
import it.tdlight.jni.TdApi;
|
||||||
import it.tdlight.jni.TdApi.AuthorizationStateClosed;
|
import it.tdlight.jni.TdApi.AuthorizationStateClosed;
|
||||||
import it.tdlight.jni.TdApi.AuthorizationStateClosing;
|
import it.tdlight.jni.TdApi.AuthorizationStateClosing;
|
||||||
@ -16,6 +17,7 @@ import it.tdlight.jni.TdApi.AuthorizationStateReady;
|
|||||||
import it.tdlight.jni.TdApi.ChatMemberStatusAdministrator;
|
import it.tdlight.jni.TdApi.ChatMemberStatusAdministrator;
|
||||||
import it.tdlight.jni.TdApi.ChatMemberStatusCreator;
|
import it.tdlight.jni.TdApi.ChatMemberStatusCreator;
|
||||||
import it.tdlight.jni.TdApi.ChatMemberStatusLeft;
|
import it.tdlight.jni.TdApi.ChatMemberStatusLeft;
|
||||||
|
import it.tdlight.jni.TdApi.GetMe;
|
||||||
import it.tdlight.jni.TdApi.GetUserPrivacySettingRules;
|
import it.tdlight.jni.TdApi.GetUserPrivacySettingRules;
|
||||||
import it.tdlight.jni.TdApi.Ok;
|
import it.tdlight.jni.TdApi.Ok;
|
||||||
import it.tdlight.jni.TdApi.Supergroup;
|
import it.tdlight.jni.TdApi.Supergroup;
|
||||||
@ -189,7 +191,7 @@ public class TransferServiceImpl implements TransferService {
|
|||||||
})
|
})
|
||||||
.then();
|
.then();
|
||||||
}))
|
}))
|
||||||
.doOnSuccess((_v) -> {
|
.doOnSuccess((clientUser) -> {
|
||||||
var newClient = new TransferClient(alias, client);
|
var newClient = new TransferClient(alias, client);
|
||||||
clients.put(phoneNumberLong, newClient);
|
clients.put(phoneNumberLong, newClient);
|
||||||
|
|
||||||
@ -313,10 +315,10 @@ public class TransferServiceImpl implements TransferService {
|
|||||||
.send(new TdApi.GetMe())
|
.send(new TdApi.GetMe())
|
||||||
.timeout(Duration.ofSeconds(5))
|
.timeout(Duration.ofSeconds(5))
|
||||||
.flatMap(MonoUtils::orElseThrow)
|
.flatMap(MonoUtils::orElseThrow)
|
||||||
.then(client.<SupergroupFullInfo>send(new TdApi.GetSupergroupFullInfo(sourceGroup.getSupergroupIdInt())))
|
.flatMap(_v -> client.<SupergroupFullInfo>send(new TdApi.GetSupergroupFullInfo(sourceGroup.getSupergroupIdInt())))
|
||||||
.flatMap(MonoUtils::orElseThrow)
|
.flatMap(MonoUtils::orElseThrow)
|
||||||
.timeout(Duration.ofSeconds(5))
|
.timeout(Duration.ofSeconds(5))
|
||||||
.then(client.<Supergroup>send(new TdApi.GetSupergroup(sourceGroup.getSupergroupIdInt())))
|
.flatMap(_v -> client.<Supergroup>send(new TdApi.GetSupergroup(sourceGroup.getSupergroupIdInt())))
|
||||||
.flatMap(MonoUtils::orElseThrow)
|
.flatMap(MonoUtils::orElseThrow)
|
||||||
.timeout(Duration.ofSeconds(5))
|
.timeout(Duration.ofSeconds(5))
|
||||||
.filter(sourceGroupFullInfo -> {
|
.filter(sourceGroupFullInfo -> {
|
||||||
@ -347,7 +349,7 @@ public class TransferServiceImpl implements TransferService {
|
|||||||
.send(new TdApi.GetMe())
|
.send(new TdApi.GetMe())
|
||||||
.flatMap(MonoUtils::orElseThrow)
|
.flatMap(MonoUtils::orElseThrow)
|
||||||
.timeout(Duration.ofSeconds(5))
|
.timeout(Duration.ofSeconds(5))
|
||||||
.then(client.<Supergroup>send(new TdApi.GetSupergroup(destGroup.getSupergroupIdInt())))
|
.flatMap(_v -> client.<Supergroup>send(new TdApi.GetSupergroup(destGroup.getSupergroupIdInt())))
|
||||||
.flatMap(MonoUtils::orElseThrow)
|
.flatMap(MonoUtils::orElseThrow)
|
||||||
.timeout(Duration.ofSeconds(5))
|
.timeout(Duration.ofSeconds(5))
|
||||||
.filter(destGroupFullInfo -> {
|
.filter(destGroupFullInfo -> {
|
||||||
@ -397,15 +399,20 @@ public class TransferServiceImpl implements TransferService {
|
|||||||
return phaseDescriptionConsumer.apply("Obtaining group members")
|
return phaseDescriptionConsumer.apply("Obtaining group members")
|
||||||
.then(percentageConsumer.apply(5)).thenReturn(clients);
|
.then(percentageConsumer.apply(5)).thenReturn(clients);
|
||||||
}).flatMap(clients -> {
|
}).flatMap(clients -> {
|
||||||
// Get the first userbot
|
|
||||||
var client = clients.stream().findAny().orElseThrow(() -> new NullPointerException("No userbots found"));
|
|
||||||
|
|
||||||
// Get the members of the source group
|
// Get the members of the source group
|
||||||
|
return Flux
|
||||||
|
.fromIterable(clients)
|
||||||
|
.flatMap(client -> {
|
||||||
return Mono.fromCallable(() -> {
|
return Mono.fromCallable(() -> {
|
||||||
var members = TransferUtils.getSupergroupMembers(client, sourceGroup.getSupergroupIdInt());
|
var members = TransferUtils.getSupergroupMembers(client, sourceGroup.getSupergroupIdInt());
|
||||||
App.getLogService().append(Level.INFO, "Source group has " + members.size() + " members.");
|
App.getLogService().append(Level.INFO, "Source group has " + members.size() + " members.");
|
||||||
return members;
|
return members;
|
||||||
}).subscribeOn(Schedulers.boundedElastic()).map(members -> Tuple3.of(client, clients, members));
|
});
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.last()
|
||||||
|
.subscribeOn(Schedulers.boundedElastic())
|
||||||
|
.map(members -> Tuple2.of(clients, members));
|
||||||
})
|
})
|
||||||
// Finished getting the list of members of the source group
|
// Finished getting the list of members of the source group
|
||||||
|
|
||||||
@ -415,10 +422,11 @@ public class TransferServiceImpl implements TransferService {
|
|||||||
.then(percentageConsumer.apply(10)).thenReturn(context);
|
.then(percentageConsumer.apply(10)).thenReturn(context);
|
||||||
})
|
})
|
||||||
.flatMap(context -> {
|
.flatMap(context -> {
|
||||||
var client = context.element1;
|
var clients = context.element1;
|
||||||
var clients = context.element2;
|
var unresolvedUsers = context.element2;
|
||||||
var unresolvedUsers = context.element3;
|
|
||||||
return Flux
|
return Flux
|
||||||
|
.fromIterable(clients)
|
||||||
|
.flatMap(client -> Flux
|
||||||
.fromIterable(unresolvedUsers)
|
.fromIterable(unresolvedUsers)
|
||||||
.flatMap(userId -> client.<User>send(new TdApi.GetUser(userId)))
|
.flatMap(userId -> client.<User>send(new TdApi.GetUser(userId)))
|
||||||
.flatMap(MonoFxUtils::orElseLogSkipError)
|
.flatMap(MonoFxUtils::orElseLogSkipError)
|
||||||
@ -428,7 +436,9 @@ public class TransferServiceImpl implements TransferService {
|
|||||||
return Mono.empty();
|
return Mono.empty();
|
||||||
})
|
})
|
||||||
.collect(Collectors.toSet())
|
.collect(Collectors.toSet())
|
||||||
.map(resolvedUsers -> Tuple3.of(client, clients, resolvedUsers));
|
)
|
||||||
|
.last()
|
||||||
|
.map(resolvedUsers -> Tuple2.of(clients, resolvedUsers));
|
||||||
})
|
})
|
||||||
// Finished resolving users
|
// Finished resolving users
|
||||||
|
|
||||||
@ -438,11 +448,16 @@ public class TransferServiceImpl implements TransferService {
|
|||||||
.then(percentageConsumer.apply(15)).thenReturn(context);
|
.then(percentageConsumer.apply(15)).thenReturn(context);
|
||||||
})
|
})
|
||||||
.flatMap(context -> {
|
.flatMap(context -> {
|
||||||
var client = context.element1;
|
var clients = context.element1;
|
||||||
var clients = context.element2;
|
var unfilteredUsers = context.element2;
|
||||||
var unfilteredUsers = context.element3;
|
|
||||||
return Flux
|
return Flux
|
||||||
.fromIterable(unfilteredUsers)
|
.fromIterable(unfilteredUsers)
|
||||||
|
.<User>flatMap(user -> {
|
||||||
|
if (this.clients.values().stream().map(TransferClient::getClientUser).noneMatch(clientUser -> clientUser.id == user.id)) {
|
||||||
|
return Mono.just(user);
|
||||||
|
}
|
||||||
|
return userStatusConsumer.apply(new UserStatus(getName(user), user.id, UserStatusType.NOT_REGULAR_USER, "")).then(Mono.empty());
|
||||||
|
})
|
||||||
.<User>flatMap(user -> {
|
.<User>flatMap(user -> {
|
||||||
if (user.haveAccess) {
|
if (user.haveAccess) {
|
||||||
return Mono.just(user);
|
return Mono.just(user);
|
||||||
@ -473,7 +488,7 @@ public class TransferServiceImpl implements TransferService {
|
|||||||
.thenReturn(user);
|
.thenReturn(user);
|
||||||
})
|
})
|
||||||
.collect(Collectors.toSet())
|
.collect(Collectors.toSet())
|
||||||
.map(resolvedUsers -> Tuple2.of(clients, resolvedUsers));
|
.map(resolvedUsers -> Tuple3.of(clients, resolvedUsers, unfilteredUsers.size()));
|
||||||
})
|
})
|
||||||
// Finished filtering unsuitable users
|
// Finished filtering unsuitable users
|
||||||
|
|
||||||
@ -485,6 +500,7 @@ public class TransferServiceImpl implements TransferService {
|
|||||||
.flatMap(context -> {
|
.flatMap(context -> {
|
||||||
var clients = context.element1;
|
var clients = context.element1;
|
||||||
var users = context.element2;
|
var users = context.element2;
|
||||||
|
var totalUsersCount = context.element3;
|
||||||
var client = clients.stream().skip(ThreadLocalRandom.current().nextInt(clients.size())).findFirst().orElseThrow();
|
var client = clients.stream().skip(ThreadLocalRandom.current().nextInt(clients.size())).findFirst().orElseThrow();
|
||||||
AtomicInteger processedUsersStats = new AtomicInteger(0);
|
AtomicInteger processedUsersStats = new AtomicInteger(0);
|
||||||
return Flux
|
return Flux
|
||||||
@ -539,13 +555,13 @@ public class TransferServiceImpl implements TransferService {
|
|||||||
})
|
})
|
||||||
.delayElements(App.getSettingsService().getDelayBetweenAdds())
|
.delayElements(App.getSettingsService().getDelayBetweenAdds())
|
||||||
.collect(Collectors.toSet())
|
.collect(Collectors.toSet())
|
||||||
.map(resolvedUsers -> Tuple2.of(clients, resolvedUsers));
|
.map(resolvedUsers -> Tuple3.of(clients, resolvedUsers, totalUsersCount));
|
||||||
})
|
})
|
||||||
// Finished transferring users
|
// Finished transferring users
|
||||||
|
|
||||||
|
|
||||||
.doOnNext(context -> {
|
.doOnNext(context -> {
|
||||||
App.getLogService().append(Level.INFO, "Transfer done. Transferred " + transferredSuccessfullyUsersStats.get() + "/" + context.element2.size() + " users");
|
App.getLogService().append(Level.INFO, "Transfer done. Transferred " + transferredSuccessfullyUsersStats.get() + "/" + context.element3 + " users");
|
||||||
})
|
})
|
||||||
|
|
||||||
.then(percentageConsumer.apply(100))
|
.then(percentageConsumer.apply(100))
|
||||||
|
Loading…
Reference in New Issue
Block a user