package im.rosetta.client; import java.util.List; import java.util.Set; import im.rosetta.client.tags.ECIAuthentificate; import io.orprotocol.ProtocolException; import io.orprotocol.Server; import io.orprotocol.client.Client; import io.orprotocol.index.ClientIndexer; import io.orprotocol.packet.Packet; /** * Менеджер клиентов */ public class ClientManager { private Server server; private ClientIndexer clientIndexer; public ClientManager(Server server) { this.server = server; this.clientIndexer = server.getClientIndexer(); } public Server getServer() { return this.server; } public ClientIndexer getClientIndexer() { return this.clientIndexer; } public boolean isClientConnected(String publicKey) { Set clients = this.clientIndexer.getClients(ECIAuthentificate.class, "publicKey", publicKey); if(clients == null){ /** * Нет клиентов с таким публичным ключом */ return false; } if(clients.size() <= 0){ /** * Нет клиентов с таким публичным ключом */ return false; } /** * Есть клиенты с таким публичным ключом */ return true; } /** * Отправить пакет ВСЕМ АВТОРИЗОВАННЫМ клиентам с публичным ключом publicKey * @param publicKey публичный ключ получателя * @param packet пакет для отправки * @throws ProtocolException если произошла ошибка при отправке пакета клиенту */ public void sendPacketToAuthorizedPK(String publicKey, Packet packet) throws ProtocolException { Set clients = this.clientIndexer.getClients(ECIAuthentificate.class, "publicKey", publicKey); if(clients == null){ /** * Нет клиентов с таким публичным ключом, значит отправлять некому */ return; } for(Client client : clients){ ECIAuthentificate eciAuthentificate = client.getTag(ECIAuthentificate.class); if(eciAuthentificate == null || !eciAuthentificate.hasAuthorized()){ /** * Если клиент не авторизован, пропускаем его, он не должен получать пакеты, * если нужно отправить пакет неавторизованному клиенту, нужно отправить его напрямую посредством client.send(packet), * а не через этот метод */ continue; } /** * Отправляем пакет каждому клиенту с таким публичным ключом (то есть всем его авторизованным сессиям/устройствам) */ client.send(packet); } } /** * Отправить пакет всем клиентам с публичными ключом как у client, кроме клиента client, который является отправителем и не должен получать этот пакет * @param client клиент * @param packet пакет для отправки * @throws ProtocolException */ public void retranslate(Client client, Packet packet) throws ProtocolException{ ECIAuthentificate eciAuthentificate = client.getTag(ECIAuthentificate.class); Set clients = this.clientIndexer .getClients(ECIAuthentificate.class, "publicKey", eciAuthentificate.getPublicKey()); if(clients == null){ /** * Нет авторизованных сессий с таким публичным ключом */ return; } for(Client c : clients){ /** * Проходим по всем устройствам с таким публичным ключом и ретранслируем им пакет, кроме того устройства что * отправило пакет */ if(c.equals(client)){ continue; } c.send(packet); } } /** * Отправить пакет всем клиентам с публичными ключами из списка publicKeys * @param publicKeys список публичных ключей получателей * @param packet пакет для отправки * @throws ProtocolException если произошла ошибка при отправке пакета клиенту */ public void sendPacketToAuthorizedPK(List publicKeys, Packet packet) throws ProtocolException { for(String publicKey : publicKeys){ this.sendPacketToAuthorizedPK(publicKey, packet); } } /** * Получить список клиентов по публичному ключу (get PublicKey clients), могут быть неавторизованные клиенты * @param publicKey публичный ключ клиента * @return список клиентов с таким публичным ключом, может быть пустым, если клиентов с таким публичным ключом нет */ public List getPKClients(String publicKey) { Set clients = this.clientIndexer.getClients(ECIAuthentificate.class, "publicKey", publicKey); if(clients == null){ /** * Нет клиентов с таким публичным ключом */ return List.of(); } return List.copyOf(clients); } }