package im.rosetta.executors; import java.util.ArrayList; import java.util.List; import im.rosetta.Failures; import im.rosetta.client.ClientManager; import im.rosetta.client.OnlineManager; import im.rosetta.client.tags.ECIAuthentificate; import im.rosetta.network.enums.NetworkStatus; import im.rosetta.network.packet.PacketOnlineState; import im.rosetta.network.packet.PacketOnlineSubscribe; import im.rosetta.network.types.PKNetworkStatus; import io.orprotocol.ProtocolException; import io.orprotocol.client.Client; import io.orprotocol.packet.PacketExecutor; public class ExecutorOnlineState extends PacketExecutor { private final OnlineManager onlineManager; private final ClientManager clientManager; public ExecutorOnlineState(OnlineManager onlineManager, ClientManager clientManager) { this.onlineManager = onlineManager; this.clientManager = clientManager; } @Override public void onPacketReceived(PacketOnlineSubscribe packet, Client client) throws Exception, ProtocolException { ECIAuthentificate eciAuthentificate = client.getTag(ECIAuthentificate.class); if(eciAuthentificate == null || !eciAuthentificate.hasAuthorized()) { /** * Клиент не авторизован */ client.disconnect(Failures.HANDSHAKE_NOT_COMPLETED); return; } /** * Устанавливаем подписку на онлайн статус указанных публичных ключей */ List publicKeys = packet.getPublicKeys(); if(publicKeys == null || publicKeys.isEmpty()) { /** * Пустой список, ничего не делаем */ return; } if(publicKeys.size() > 20) { /** * Слишком много подписок за один раз */ client.disconnect(Failures.TOO_MANY_ONLINE_SUBSCRIPTIONS); return; } for (String targetPublicKey : publicKeys) { this.onlineManager.subscribe(client, targetPublicKey); } /** * Сразу же формируем и отправляем клиенту онлайн статус для указанных публичных ключей, чтобы клиент не ждал обновления статуса, * а получил его сразу после подписки */ PacketOnlineState onlineStates = new PacketOnlineState(); List onlineStatusList = new ArrayList<>(); for (String targetPublicKey : publicKeys) { NetworkStatus networkStatus = this.clientManager.isClientConnected(targetPublicKey) ? NetworkStatus.ONLINE : NetworkStatus.OFFLINE; PKNetworkStatus pkNetworkStatus = new PKNetworkStatus(); pkNetworkStatus.setPublicKey(targetPublicKey); pkNetworkStatus.setNetworkStatus(networkStatus); onlineStatusList.add(pkNetworkStatus); } onlineStates.setPkNetworkStatuses(onlineStatusList); client.send(onlineStates); } }