private async Task Connection_PacketReceived(object sender, PacketReceivedEventArgs args) { if (sender == null) { throw new ArgumentNullException(nameof(sender)); } Interlocked.Increment(ref _packetCount); if (typeof(RequestPacket).IsAssignableFrom(args.Packet.GetPacketType())) { if (!string.IsNullOrWhiteSpace(args.Packet.Destination)) { var sendCount = 0; var connections = ConnectionProvider.GetConnections(args.Packet.Destination, true).ToArray(); Log.Info($"Sending {args.Packet} to {connections.Length} connections: {string.Join(",", connections.Take(10))}"); try { foreach (var connection in connections) { try { var response = await connection.Send(args.Packet); if (args.Packet.Flags.HasFlag(PacketFlag.AckRequired)) { if (response == null) { throw new ErrorResponseException(ErrorResponseCodes.UnhandledRequest, $"Packet {args.Packet} routed to {args.Packet.Destination}, but they didn't handle the request.", false); } var responsePacket = (ResponsePacket)response; await args.Connection.Respond(args.PacketId, responsePacket); } sendCount++; } catch (Exception ex) when(!(ex is ErrorResponseException)) { Log.Warn(ex); } } if (sendCount < 1) { Log.Warn($"Unable to deliver packet to user {args.Packet.Destination}, they are offline or the destination is invalid."); throw new ErrorResponseException(ErrorResponseCodes.UserOffline, $"Unable to deliver packet to user {args.Packet.Destination}, they are offline of the destination is invalid.", false); } } catch (ErrorResponseException ex) { var err = new ErrorResponseData(ex.Code, ex.Message, ex.IsCritical); await args.Connection.Respond(args.PacketId, new ResponsePacket(err)); } Log.Info($"Sent {args.Packet} to {sendCount} clients"); args.IsHandled = true; } } }
public ErrorResponseException(ErrorResponseData data) : this(data.Code, data.Message, data.IsCritical) { }