TransferBot/src/main/java/it/cavallium/TransferClient.java

127 lines
4.4 KiB
Java

package it.cavallium;
import it.tdlight.jni.TdApi;
import it.tdlight.jni.TdApi.AuthorizationState;
import it.tdlight.jni.TdApi.AuthorizationStateReady;
import it.tdlight.jni.TdApi.Chat;
import it.tdlight.jni.TdApi.ChatMemberStatusAdministrator;
import it.tdlight.jni.TdApi.GetSupergroupFullInfo;
import it.tdlight.jni.TdApi.Object;
import it.tdlight.jni.TdApi.Supergroup;
import it.tdlight.jni.TdApi.SupergroupFullInfo;
import it.tdlight.jni.TdApi.Update;
import it.tdlight.jni.TdApi.UpdateAuthorizationState;
import it.tdlight.jni.TdApi.UpdateNewChat;
import it.tdlight.jni.TdApi.UpdateSupergroup;
import it.tdlight.jni.TdApi.UpdateSupergroupFullInfo;
import it.tdlight.tdlibsession.td.TdResult;
import it.tdlight.tdlibsession.td.easy.AsyncTdEasy;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
public class TransferClient {
private final AsyncTdEasy client;
private final ConcurrentHashMap<Integer, Supergroup> supergroupInfos = new ConcurrentHashMap<>();
private final ConcurrentHashMap<Integer, SupergroupFullInfo> supergroupFullInfos = new ConcurrentHashMap<>();
private final ConcurrentHashMap<Long, Chat> chats = new ConcurrentHashMap<>();
public TransferClient(AsyncTdEasy client) {
this.client = client;
this.client.getIncomingUpdates()
.subscribeOn(Schedulers.newParallel("bot_updates"))
.flatMap(this::onUpdate)
.subscribe();
}
private Mono<Void> onUpdate(Update update) {
switch (update.getConstructor()) {
case UpdateSupergroup.CONSTRUCTOR:
return this.onUpdateSupergroup(((UpdateSupergroup) update).supergroup);
case UpdateSupergroupFullInfo.CONSTRUCTOR:
return this.onUpdateSupergroupFullInfo(
((UpdateSupergroupFullInfo) update).supergroupId,
((UpdateSupergroupFullInfo) update).supergroupFullInfo);
case UpdateNewChat.CONSTRUCTOR:
return this.onChat(((UpdateNewChat) update).chat);
case UpdateAuthorizationState.CONSTRUCTOR:
return this.onUpdateAuthorizationState(((UpdateAuthorizationState) update).authorizationState);
default:
return Mono.empty();
}
}
private Mono<Void> onUpdateAuthorizationState(AuthorizationState authorizationState) {
switch (authorizationState.getConstructor()) {
case AuthorizationStateReady.CONSTRUCTOR:
return TransferUtils.getAllHomeChats(this).flatMap(this::onChat).then();
default:
return Mono.empty();
}
}
private Mono<Void> onChat(Chat chat) {
if (chats.put(chat.id, chat) == null) {
// ok
}
return Mono.empty();
}
private Mono<Void> onUpdateSupergroup(Supergroup supergroup) {
if (supergroupInfos.put(supergroup.id, supergroup) == null) {
return this
.<SupergroupFullInfo>send(new GetSupergroupFullInfo(supergroup.id))
.filter(TdResult::succeeded)
.map(TdResult::result)
.flatMap(supergroupFullInfo -> onUpdateSupergroupFullInfo(supergroup.id, supergroupFullInfo));
}
return Mono.empty();
}
private Mono<Void> onUpdateSupergroupFullInfo(int id, SupergroupFullInfo supergroupFullInfo) {
if (supergroupFullInfos.put(id, supergroupFullInfo) == null) {
// ok
}
return Mono.empty();
}
/**
* Sends request to TDLib.
* @return The response or {@link TdApi.Error}.
*/
public <T extends Object> Mono<TdResult<T>> send(TdApi.Function request) {
return client.send(request);
}
public Set<BaseChatInfo> getAdminSupergroups(boolean canRestrictMembers, boolean canInviteUsers) {
return supergroupFullInfos.entrySet().stream().flatMap(entry -> {
int id = entry.getKey();
var fullInfo = entry.getValue();
var chatInfo = chats.get(TransferUtils.chatEntityIdToChatId(id, TChatType.SUPERGROUP));
var baseInfo = supergroupInfos.get(id);
if (chatInfo == null || baseInfo == null) {
return Stream.<BaseChatInfo>empty();
} else {
if (baseInfo.status.getConstructor() != ChatMemberStatusAdministrator.CONSTRUCTOR) {
return Stream.empty();
}
var adminStatus = (ChatMemberStatusAdministrator) baseInfo.status;
if (!adminStatus.canRestrictMembers && canRestrictMembers) {
return Stream.empty();
}
if (!adminStatus.canInviteUsers && canInviteUsers) {
return Stream.empty();
}
var baseChatInfo = new BaseChatInfo(id, chatInfo.title);
return Stream.<BaseChatInfo>of(baseChatInfo);
}
}).collect(Collectors.toSet());
}
}