Фикс двойных уведомлений при подключении нового устройства

This commit is contained in:
2026-02-21 15:19:50 +02:00
parent 38c8e07ef7
commit ae435c8486
3 changed files with 37 additions and 9 deletions

View File

@@ -203,7 +203,7 @@ public class Boot {
this.packetManager.registerExecutor(20, new Executor20GroupJoin()); this.packetManager.registerExecutor(20, new Executor20GroupJoin());
this.packetManager.registerExecutor(21, new Executor21GroupLeave()); this.packetManager.registerExecutor(21, new Executor21GroupLeave());
this.packetManager.registerExecutor(22, new Executor22GroupBan()); this.packetManager.registerExecutor(22, new Executor22GroupBan());
this.packetManager.registerExecutor(24, new Executor24DeviceResolve(this.clientManager, this.eventManager)); this.packetManager.registerExecutor(24, new Executor24DeviceResolve(this.clientManager, this.eventManager, this.packetManager));
this.packetManager.registerExecutor(25, new Executor25Sync(this.packetManager)); this.packetManager.registerExecutor(25, new Executor25Sync(this.packetManager));
} }

View File

@@ -6,7 +6,9 @@ import im.rosetta.Failures;
import im.rosetta.client.ClientManager; import im.rosetta.client.ClientManager;
import im.rosetta.client.tags.ECIAuthentificate; import im.rosetta.client.tags.ECIAuthentificate;
import im.rosetta.client.tags.ECIDevice; import im.rosetta.client.tags.ECIDevice;
import im.rosetta.database.entity.Buffer;
import im.rosetta.database.entity.Device; import im.rosetta.database.entity.Device;
import im.rosetta.database.repository.BufferRepository;
import im.rosetta.database.repository.DeviceRepository; import im.rosetta.database.repository.DeviceRepository;
import im.rosetta.event.EventManager; import im.rosetta.event.EventManager;
import im.rosetta.event.events.handshake.HandshakeCompletedEvent; import im.rosetta.event.events.handshake.HandshakeCompletedEvent;
@@ -15,10 +17,11 @@ import im.rosetta.packet.Packet24DeviceResolve;
import im.rosetta.packet.runtime.DeviceSolution; import im.rosetta.packet.runtime.DeviceSolution;
import im.rosetta.packet.runtime.HandshakeStage; import im.rosetta.packet.runtime.HandshakeStage;
import im.rosetta.service.dispatch.DeviceDispatcher; import im.rosetta.service.dispatch.DeviceDispatcher;
import im.rosetta.service.services.BufferService;
import io.orprotocol.ProtocolException; import io.orprotocol.ProtocolException;
import io.orprotocol.client.Client; import io.orprotocol.client.Client;
import io.orprotocol.packet.PacketExecutor; import io.orprotocol.packet.PacketExecutor;
import io.orprotocol.packet.PacketManager;
public class Executor24DeviceResolve extends PacketExecutor<Packet24DeviceResolve> { public class Executor24DeviceResolve extends PacketExecutor<Packet24DeviceResolve> {
@@ -26,11 +29,14 @@ public class Executor24DeviceResolve extends PacketExecutor<Packet24DeviceResolv
private final EventManager eventManager; private final EventManager eventManager;
private final DeviceRepository deviceRepository = new DeviceRepository(); private final DeviceRepository deviceRepository = new DeviceRepository();
private final DeviceDispatcher deviceDispatcher; private final DeviceDispatcher deviceDispatcher;
private final BufferRepository bufferRepository = new BufferRepository();
private final BufferService bufferService;
public Executor24DeviceResolve(ClientManager clientManager, EventManager eventManager) { public Executor24DeviceResolve(ClientManager clientManager, EventManager eventManager, PacketManager packetManager) {
this.clientManager = clientManager; this.clientManager = clientManager;
this.eventManager = eventManager; this.eventManager = eventManager;
this.deviceDispatcher = new DeviceDispatcher(clientManager); this.deviceDispatcher = new DeviceDispatcher(clientManager);
this.bufferService = new BufferService(this.bufferRepository, packetManager);
} }
@Override @Override
@@ -68,15 +74,18 @@ public class Executor24DeviceResolve extends PacketExecutor<Packet24DeviceResolv
device.setPublicKey(eciAuthentificate.getPublicKey()); device.setPublicKey(eciAuthentificate.getPublicKey());
device.setDeviceOs(deviceTag.getDeviceOs()); device.setDeviceOs(deviceTag.getDeviceOs());
device.setDeviceName(deviceTag.getDeviceName()); device.setDeviceName(deviceTag.getDeviceName());
/**
* TODO: Здесь можно реализовать отключение синхронизации,
* например если у пользователя отключена синхронизация, то при разрешении нового устройства
* можно устанавливать leaveTime как текущее время, тогда сообщения новому устройству не загрузятся.
* Если установить leaveTime в 0, то синхронизируются все сообщения которые есть на сервере
*/
device.setSyncTime(0L); device.setSyncTime(0L);
this.deviceRepository.save(device); this.deviceRepository.save(device);
/**
* Сбрасываем клиенту все подтверждения устройств, чтобы исключить спам запросами,
* а так же исправить баг, когда при подключении первого устройства показывалось уведомление
* о новом входе.
*
* 9 ID пакета - Packet9DeviceNew
*/
this.bufferService.deletePacketsFromBuffer(eciAuthentificate.getPublicKey(), 9, 0);
/** /**
* Устанавливаем пользователю успешный хэндшейк * Устанавливаем пользователю успешный хэндшейк
*/ */
@@ -118,6 +127,14 @@ public class Executor24DeviceResolve extends PacketExecutor<Packet24DeviceResolv
* о присоединении нового устройства) * о присоединении нового устройства)
*/ */
this.deviceDispatcher.sendDevices(eciAuthentificate.getPublicKey()); this.deviceDispatcher.sendDevices(eciAuthentificate.getPublicKey());
/**
* Сбрасываем клиенту все подтверждения устройств, чтобы исключить спам запросами,
* а так же исправить баг, когда при подключении первого устройства показывалось уведомление
* о новом входе.
*
* 9 ID пакета - Packet9DeviceNew
*/
this.bufferService.deletePacketsFromBuffer(eciAuthentificate.getPublicKey(), 9, 0);
break; break;
} }
} }

View File

@@ -117,6 +117,17 @@ public class BufferService extends Service<BufferRepository> {
*/ */
public void deletePacketsFromBuffer(String to, Packet packet, long fromTimestampMs) { public void deletePacketsFromBuffer(String to, Packet packet, long fromTimestampMs) {
int packetId = this.packetManager.getPacketIdByClass(packet.getClass()); int packetId = this.packetManager.getPacketIdByClass(packet.getClass());
this.deletePacketsFromBuffer(to, packetId, fromTimestampMs);
}
/**
* Удаляет из буфера все пакеты для определенного клиента с публичным ключом to, которые были добавлены
* в буфер после fromTimestampMs и имееют такой же ID пакета как и переданный
* @param to публичный ключ получателя пакета
* @param packetId ID пакета, который нужно удалить
* @param fromTimestampMs метка времени в миллисекундах, после которой были добавлены пакеты, которые нужно удалить
*/
public void deletePacketsFromBuffer(String to, int packetId, long fromTimestampMs){
String hql = "DELETE FROM Buffer WHERE to = :to AND packetId = :packetId AND timestamp > :timestamp"; String hql = "DELETE FROM Buffer WHERE to = :to AND packetId = :packetId AND timestamp > :timestamp";
HashMap<String, Object> parameters = new HashMap<>(); HashMap<String, Object> parameters = new HashMap<>();
parameters.put("to", to); parameters.put("to", to);