//
// ClientService.cs
//
// Copyright (c) František Boháček. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System.Diagnostics;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using NosSmooth.Comms.Core;
using NosSmooth.Comms.Data.Messages;
using NosSmooth.Comms.Local;
using NosSmooth.Core.Contracts;
using NosSmooth.Core.Extensions;
using NosSmooth.PacketSerializer.Extensions;
using NosSmooth.PacketSerializer.Packets;
namespace ConsolePacketLogger;
///
public class ClientService : BackgroundService
{
private readonly IPacketTypesRepository _packetTypesRepository;
private readonly CommsInjector _injector;
private readonly IHostApplicationLifetime _lifetime;
private readonly ILogger _logger;
private readonly PacketLoggerOptions _options;
///
/// Initializes a new instance of the class.
///
/// The packet types repository.
/// The injector.
/// The lifetime.
/// The logger.
/// The options.
public ClientService
(
IPacketTypesRepository packetTypesRepository,
CommsInjector injector,
IHostApplicationLifetime lifetime,
ILogger logger,
IOptions options
)
{
_packetTypesRepository = packetTypesRepository;
_injector = injector;
_lifetime = lifetime;
_logger = logger;
_options = options.Value;
}
///
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
var packetsResult = _packetTypesRepository.AddDefaultPackets();
if (!packetsResult.IsSuccess)
{
_logger.LogResultError(packetsResult);
}
var process = Process.GetProcessById(_options.ProcessId);
var connectionResult = await _injector.EstablishNamedPipesConnectionAsync
(process, stoppingToken, stoppingToken);
if (!connectionResult.IsDefined(out var connection))
{
_logger.LogResultError(connectionResult);
_lifetime.StopApplication();
return;
}
var handshakeResponseResult = await connection.Connection
.ContractHanshake(new HandshakeRequest("ConsolePacketLogger example", true, false))
.WaitForAsync(DefaultStates.ResponseObtained, ct: stoppingToken);
if (!handshakeResponseResult.IsDefined(out var handshakeResponse))
{
_logger.LogResultError(handshakeResponseResult);
_lifetime.StopApplication();
return;
}
_logger.LogInformation
(
$"Connected to {handshakeResponse.CharacterName ?? "Not in game"} ({handshakeResponse.CharacterId?.ToString() ?? "Not in game"})"
);
var runResult = await connection.Connection.RunHandlerAsync(stoppingToken);
if (!runResult.IsSuccess)
{
_logger.LogResultError(runResult);
}
_lifetime.StopApplication();
}
}