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

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(21, new Executor21GroupLeave());
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));
}

View File

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

View File

@@ -117,6 +117,17 @@ public class BufferService extends Service<BufferRepository> {
*/
public void deletePacketsFromBuffer(String to, Packet packet, long fromTimestampMs) {
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";
HashMap<String, Object> parameters = new HashMap<>();
parameters.put("to", to);