// // Licensed under the MIT License. See LICENSE file in the project root for full license information. // namespace MUnique.OpenMU.Persistence.EntityFramework; using System.Threading; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using MUnique.OpenMU.Persistence.EntityFramework.Model; /// /// Persistence context which is used by in-game players. /// internal class PlayerContext : CachingEntityFrameworkContext, IPlayerContext { /// /// Initializes a new instance of the class. /// /// The context. /// The repository provider. /// The logger. public PlayerContext(DbContext context, IContextAwareRepositoryProvider repositoryProvider, ILogger logger) : base(context, repositoryProvider, null, logger) { } /// public async ValueTask GetLetterBodyByHeaderIdAsync(Guid headerId, CancellationToken cancellationToken = default) { using var context = this.RepositoryProvider.ContextStack.UseContext(this); if (this.RepositoryProvider.GetRepository() is { } repository) { return await repository.GetBodyByHeaderIdAsync(headerId, cancellationToken).ConfigureAwait(false); } return null; } /// public async ValueTask CanSaveLetterAsync(Interfaces.LetterHeader letterHeader, CancellationToken cancellationToken = default) { if (letterHeader is not Model.LetterHeader persistentHeader) { return false; } persistentHeader.Receiver = await this.Context.Set().FirstOrDefaultAsync(c => c.Name == letterHeader.ReceiverName, cancellationToken).ConfigureAwait(false); return persistentHeader.Receiver != null; } /// public async ValueTask AuthenticateAsync(string loginName, string password, CancellationToken cancellationToken = default) { using (this.RepositoryProvider.ContextStack.UseContext(this)) { if (this.RepositoryProvider.GetRepository() is { } accountRepository) { return await accountRepository.AuthenticateAsync(loginName, password, cancellationToken).ConfigureAwait(false); } } return null; } /// public async ValueTask GetAccountByLoginNameAsync(string loginName, string password, CancellationToken cancellationToken = default) { using (this.RepositoryProvider.ContextStack.UseContext(this)) { if (this.RepositoryProvider.GetRepository() is { } accountRepository) { return await accountRepository.GetAccountByLoginNameAsync(loginName, password, cancellationToken).ConfigureAwait(false); } } return null; } /// public async ValueTask GetAccountByLoginNameAsync(string loginName, CancellationToken cancellationToken = default) { using (this.RepositoryProvider.ContextStack.UseContext(this)) { if (this.RepositoryProvider.GetRepository() is { } accountRepository) { return await accountRepository.GetAccountByLoginNameAsync(loginName, cancellationToken).ConfigureAwait(false); } } return null; } /// public async ValueTask> GetAccountsOrderedByLoginNameAsync(int skip, int count, CancellationToken cancellationToken = default) { using (this.RepositoryProvider.ContextStack.UseContext(this)) { return await this.Context.Set().AsNoTracking().OrderBy(a => a.LoginName).Skip(skip).Take(count).ToListAsync(cancellationToken).ConfigureAwait(false); } } /// public async ValueTask> SearchAccountsAsync(string searchTerm, int skip, int count, CancellationToken cancellationToken = default) { using (this.RepositoryProvider.ContextStack.UseContext(this)) { // Invariant: this one runs in .NET, so it must not depend on the server's locale - in a // Turkish one, "I".ToLower() is a dotless "ı" and the term would match nothing. The // ToLower() calls inside the query below are a different matter: they are translated to // the database's own lower(), which is why they cannot take a culture. var term = searchTerm.ToLowerInvariant(); return await this.Context.Set().AsNoTracking() .Where(a => a.LoginName.ToLower().Contains(term) || a.RawCharacters.Any(c => c.Name.ToLower().Contains(term))) .OrderBy(a => a.LoginName) .Skip(skip) .Take(count) .ToListAsync(cancellationToken).ConfigureAwait(false); } } /// public async ValueTask GetAccountByCharacterNameAsync(string characterName, CancellationToken cancellationToken = default) { using (this.RepositoryProvider.ContextStack.UseContext(this)) { if (this.RepositoryProvider.GetRepository() is { } accountRepository) { return await accountRepository.GetAccountByCharacterNameAsync(characterName, cancellationToken).ConfigureAwait(false); } } return null; } }