130 lines
No EOL
4.4 KiB
C#
130 lines
No EOL
4.4 KiB
C#
// WingsEmu
|
|
//
|
|
// Developed by NosWings Team
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using PhoenixLib.DAL;
|
|
using PhoenixLib.Events;
|
|
using PhoenixLib.Logging;
|
|
using Polly;
|
|
using Polly.Retry;
|
|
using WingsAPI.Communication;
|
|
using WingsAPI.Communication.DbServer.AccountService;
|
|
using WingsAPI.Communication.DbServer.CharacterService;
|
|
using WingsAPI.Data.Account;
|
|
using WingsAPI.Data.Character;
|
|
using WingsEmu.Game;
|
|
using WingsEmu.Game.Characters;
|
|
using WingsEmu.Game.Characters.Events;
|
|
using WingsEmu.Packets.Enums;
|
|
|
|
namespace WingsEmu.Plugins.BasicImplementations.Event.Characters;
|
|
|
|
public class SessionSaveEventHandler : IAsyncEventProcessor<SessionSaveEvent>
|
|
{
|
|
private readonly IAccountService _accountService;
|
|
private readonly ICharacterService _characterService;
|
|
private readonly IMapper<AccountDTO, Account> _mapper;
|
|
private readonly IPlayerEntityFactory _playerEntityFactory;
|
|
|
|
public SessionSaveEventHandler(IPlayerEntityFactory playerEntityFactory, ICharacterService characterService, IAccountService accountService, IMapper<AccountDTO, Account> mapper)
|
|
{
|
|
_playerEntityFactory = playerEntityFactory;
|
|
_characterService = characterService;
|
|
_accountService = accountService;
|
|
_mapper = mapper;
|
|
}
|
|
|
|
public async Task HandleAsync(SessionSaveEvent e, CancellationToken cancellation)
|
|
{
|
|
IPlayerEntity playerEntity = e.Sender.PlayerEntity;
|
|
AccountDTO account = _mapper.Map(e.Sender.Account);
|
|
long accountId = account.Id;
|
|
AsyncRetryPolicy policy = Policy.Handle<Exception>().RetryAsync(3,
|
|
(exception, i1) => Log.Error($"[CHARACTER_SAVE][ACCOUNT_ID: '{accountId.ToString()}'] Failed to save characters, try {i1.ToString()}. ", exception));
|
|
|
|
AccountSaveResponse response = null;
|
|
try
|
|
{
|
|
response = await policy.ExecuteAsync(() => _accountService.SaveAccount(new AccountSaveRequest
|
|
{
|
|
AccountDto = account
|
|
}));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error($"[CHARACTER_SAVE][ACCOUNT_ID: '{account.Id.ToString()}'] Unexpected error: ", ex);
|
|
}
|
|
|
|
if (response?.ResponseType != RpcResponseType.SUCCESS)
|
|
{
|
|
Log.Warn($"[CHARACTER_SAVE][ACCOUNT_ID: '{account.Id.ToString()}'] Failed to save account");
|
|
}
|
|
|
|
CharacterDTO characterDto = _playerEntityFactory.CreateCharacterDto(playerEntity);
|
|
DbServerSaveCharacterResponse response2 = null;
|
|
try
|
|
{
|
|
response2 = await _characterService.SaveCharacter(new DbServerSaveCharacterRequest
|
|
{
|
|
Character = characterDto
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error($"[CHARACTER_SAVE][CHARACTER_ID: '{characterDto.Id.ToString()}'] Unexpected error: ", ex);
|
|
}
|
|
|
|
if (response2?.RpcResponseType != RpcResponseType.SUCCESS)
|
|
{
|
|
Log.Warn($"[CHARACTER_SAVE][CHARACTER_ID: '{characterDto.Id.ToString()}'] Failed to save character");
|
|
}
|
|
|
|
Log.Warn($"{characterDto.Name} was saved");
|
|
|
|
CheckPlayerMute(playerEntity);
|
|
AccountPenaltyMultiSaveResponse response3 = null;
|
|
try
|
|
{
|
|
response3 = await _accountService.SaveAccountPenalties(new AccountPenaltyMultiSaveRequest
|
|
{
|
|
AccountPenaltyDtos = e.Sender.Account.Logs
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error($"[CHARACTER_SAVE][ACCOUNT_ID: '{account.Id.ToString()}'] Unexpected error: ", ex);
|
|
}
|
|
|
|
if (response3?.ResponseType != RpcResponseType.SUCCESS)
|
|
{
|
|
Log.Warn($"[CHARACTER_SAVE][ACCOUNT_ID: '{account.Id.ToString()}'] Failed to save account's penalties");
|
|
}
|
|
}
|
|
|
|
private void CheckPlayerMute(IPlayerEntity playerEntity)
|
|
{
|
|
if (!playerEntity.MuteRemainingTime.HasValue)
|
|
{
|
|
return;
|
|
}
|
|
|
|
AccountPenaltyDto penalty = playerEntity.Session.Account.Logs.FirstOrDefault(x => x.PenaltyType == PenaltyType.Muted && x.RemainingTime.HasValue);
|
|
if (penalty == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (playerEntity.MuteRemainingTime.Value.TotalMilliseconds > 0)
|
|
{
|
|
penalty.RemainingTime = (int?)playerEntity.MuteRemainingTime.Value.TotalSeconds;
|
|
}
|
|
else
|
|
{
|
|
penalty.RemainingTime = null;
|
|
}
|
|
}
|
|
} |