2018-11-25 21:00:36 -05:00
using Microsoft.EntityFrameworkCore ;
2018-04-08 02:44:42 -04:00
using SharedLibraryCore.Database ;
using SharedLibraryCore.Database.Models ;
2019-04-25 22:05:35 -04:00
using SharedLibraryCore.Dtos ;
2018-11-25 21:00:36 -05:00
using System ;
using System.Collections.Generic ;
using System.Linq ;
using System.Threading.Tasks ;
2018-11-05 22:01:29 -05:00
using static SharedLibraryCore . Database . Models . EFClient ;
2017-11-25 20:29:58 -05:00
2018-04-08 02:44:42 -04:00
namespace SharedLibraryCore.Services
2017-11-25 20:29:58 -05:00
{
2017-11-29 19:35:50 -05:00
2017-11-25 20:29:58 -05:00
public class ClientService : Interfaces . IEntityService < EFClient >
{
public async Task < EFClient > Create ( EFClient entity )
{
2017-11-29 19:35:50 -05:00
using ( var context = new DatabaseContext ( ) )
2017-11-25 20:29:58 -05:00
{
2019-04-05 14:34:03 -04:00
int? linkId = null ;
int? aliasId = null ;
if ( entity . IPAddress ! = null )
{
var existingAlias = await context . Aliases
. Select ( _alias = > new { _alias . AliasId , _alias . LinkId , _alias . IPAddress , _alias . Name } )
. FirstOrDefaultAsync ( _alias = > _alias . IPAddress = = entity . IPAddress ) ;
if ( existingAlias ! = null )
{
2019-04-06 22:48:49 -04:00
entity . CurrentServer . Logger . WriteDebug ( $"[create] client with new GUID {entity} has existing link {existingAlias.LinkId}" ) ;
2019-04-05 14:34:03 -04:00
linkId = existingAlias . LinkId ;
if ( existingAlias . Name = = entity . Name )
{
2019-04-06 22:48:49 -04:00
entity . CurrentServer . Logger . WriteDebug ( $"[create] client with new GUID {entity} has existing alias {existingAlias.AliasId}" ) ;
2019-04-05 14:34:03 -04:00
aliasId = existingAlias . AliasId ;
}
}
}
2018-11-25 21:00:36 -05:00
var client = new EFClient ( )
{
Level = Permission . User ,
FirstConnection = DateTime . UtcNow ,
LastConnection = DateTime . UtcNow ,
2019-04-05 14:34:03 -04:00
NetworkId = entity . NetworkId
2018-11-25 21:00:36 -05:00
} ;
2019-04-06 22:48:49 -04:00
context . Clients . Add ( client ) ;
2019-06-11 09:00:14 -04:00
2019-04-05 22:15:17 -04:00
// they're just using a new GUID
if ( aliasId . HasValue )
2018-11-25 21:00:36 -05:00
{
2019-04-06 22:48:49 -04:00
entity . CurrentServer . Logger . WriteDebug ( $"[create] setting {entity}'s alias id and linkid to ({aliasId.Value}, {linkId.Value})" ) ;
2019-04-05 22:15:17 -04:00
client . CurrentAliasId = aliasId . Value ;
2019-04-05 14:34:03 -04:00
client . AliasLinkId = linkId . Value ;
}
2019-04-05 22:15:17 -04:00
// link was found but they don't have an exact alias
else if ( ! aliasId . HasValue & & linkId . HasValue )
2019-04-05 14:34:03 -04:00
{
2019-04-06 22:48:49 -04:00
entity . CurrentServer . Logger . WriteDebug ( $"[create] setting {entity}'s linkid to {linkId.Value}, but creating new alias" ) ;
2019-04-05 22:15:17 -04:00
client . AliasLinkId = linkId . Value ;
2019-04-06 22:48:49 -04:00
client . CurrentAlias = new EFAlias ( )
2019-04-05 22:15:17 -04:00
{
Name = entity . Name ,
DateAdded = DateTime . UtcNow ,
IPAddress = entity . IPAddress ,
LinkId = linkId . Value
} ;
2019-04-05 14:34:03 -04:00
}
2019-04-05 22:15:17 -04:00
// brand new players (supposedly)
2019-04-05 14:34:03 -04:00
else
{
2019-04-06 22:48:49 -04:00
entity . CurrentServer . Logger . WriteDebug ( $"[create] creating new Link and Alias for {entity}" ) ;
var link = new EFAliasLink ( ) ;
var alias = new EFAlias ( )
2019-04-05 14:34:03 -04:00
{
Name = entity . Name ,
DateAdded = DateTime . UtcNow ,
IPAddress = entity . IPAddress ,
2019-04-06 22:48:49 -04:00
Link = link
2019-04-05 14:34:03 -04:00
} ;
2019-04-06 22:48:49 -04:00
link . Children . Add ( alias ) ;
client . AliasLink = link ;
client . CurrentAlias = alias ;
2019-04-05 14:34:03 -04:00
}
2018-11-25 21:00:36 -05:00
await context . SaveChangesAsync ( ) ;
return client ;
}
}
2019-01-02 19:32:39 -05:00
private async Task UpdateAlias ( string name , int? ip , EFClient entity , DatabaseContext context )
2018-11-25 21:00:36 -05:00
{
2019-01-02 19:32:39 -05:00
// entity is the tracked db context item
// get all aliases by IP address and LinkId
var iqAliases = context . Aliases
. Include ( a = > a . Link )
2019-04-02 21:20:37 -04:00
// we only want alias that have the same IP address or share a link
2019-04-05 14:34:03 -04:00
. Where ( _alias = > _alias . IPAddress = = ip | | ( _alias . LinkId = = entity . AliasLinkId ) ) ;
2018-12-03 20:21:13 -05:00
#if DEBUG = = true
2019-01-02 19:32:39 -05:00
var aliasSql = iqAliases . ToSql ( ) ;
2018-12-03 20:21:13 -05:00
#endif
2019-01-02 19:32:39 -05:00
var aliases = await iqAliases . ToListAsync ( ) ;
2019-07-16 16:27:19 -04:00
2019-01-02 19:32:39 -05:00
// see if they have a matching IP + Name but new NetworkId
var existingExactAlias = aliases . FirstOrDefault ( a = > a . Name = = name & & a . IPAddress = = ip ) ;
2019-04-02 21:20:37 -04:00
bool hasExactAliasMatch = existingExactAlias ! = null ;
2018-11-25 21:00:36 -05:00
2019-01-02 19:32:39 -05:00
// if existing alias matches link them
2019-04-02 21:20:37 -04:00
var newAliasLink = existingExactAlias ? . Link ;
// if no exact matches find the first IP or LinkId that matches
2019-06-24 12:01:34 -04:00
newAliasLink = newAliasLink ? ? aliases . OrderBy ( _alias = > _alias . LinkId ) . FirstOrDefault ( ) ? . Link ;
2019-04-02 21:20:37 -04:00
// if no matches are found, use our current one ( it will become permanent )
newAliasLink = newAliasLink ? ? entity . AliasLink ;
2019-01-02 19:32:39 -05:00
bool hasExistingAlias = aliases . Count > 0 ;
2019-04-02 21:20:37 -04:00
bool isAliasLinkUpdated = newAliasLink . AliasLinkId ! = entity . AliasLink . AliasLinkId ;
2019-01-02 19:32:39 -05:00
2019-06-24 12:01:34 -04:00
// update each of the aliases where this is no IP but the name is identical
foreach ( var alias in aliases . Where ( _alias = > ( _alias . IPAddress = = null | | _alias . IPAddress = = 0 ) ) )
{
alias . IPAddress = ip ;
}
await context . SaveChangesAsync ( ) ;
2019-04-02 21:20:37 -04:00
// this happens when the link we found is different than the one we create before adding an IP
if ( isAliasLinkUpdated )
2019-01-02 19:32:39 -05:00
{
2019-04-07 21:14:59 -04:00
entity . CurrentServer . Logger . WriteDebug ( $"[updatealias] found a link for {entity} so we are updating link from {entity.AliasLink.AliasLinkId} to {newAliasLink.AliasLinkId}" ) ;
2019-01-02 19:32:39 -05:00
2019-04-02 21:20:37 -04:00
var oldAliasLink = entity . AliasLink ;
2019-01-02 19:32:39 -05:00
2019-04-05 22:15:17 -04:00
// update all the clients that have the old alias link
await context . Clients
. Where ( _client = > _client . AliasLinkId = = oldAliasLink . AliasLinkId )
. ForEachAsync ( _client = > _client . AliasLinkId = newAliasLink . AliasLinkId ) ;
2019-04-02 21:20:37 -04:00
entity . AliasLink = newAliasLink ;
entity . AliasLinkId = newAliasLink . AliasLinkId ;
2018-12-31 21:52:19 -05:00
2019-04-02 21:20:37 -04:00
// update all previous aliases
await context . Aliases
. Where ( _alias = > _alias . LinkId = = oldAliasLink . AliasLinkId )
2019-04-05 14:34:03 -04:00
. ForEachAsync ( _alias = > _alias . LinkId = newAliasLink . AliasLinkId ) ;
2018-12-31 21:52:19 -05:00
2019-04-02 21:20:37 -04:00
await context . SaveChangesAsync ( ) ;
// we want to delete the now inactive alias
context . AliasLinks . Remove ( oldAliasLink ) ;
await context . SaveChangesAsync ( ) ;
2019-01-02 19:32:39 -05:00
}
2018-12-31 21:52:19 -05:00
2019-01-02 19:32:39 -05:00
// the existing alias matches ip and name, so we can just ignore the temporary one
2019-04-02 21:20:37 -04:00
if ( hasExactAliasMatch )
2019-01-02 19:32:39 -05:00
{
2019-04-07 21:14:59 -04:00
entity . CurrentServer . Logger . WriteDebug ( $"[updatealias] {entity} has exact alias match" ) ;
2019-04-02 21:20:37 -04:00
var oldAlias = entity . CurrentAlias ;
2019-01-02 19:32:39 -05:00
entity . CurrentAliasId = existingExactAlias . AliasId ;
entity . CurrentAlias = existingExactAlias ;
await context . SaveChangesAsync ( ) ;
2019-04-02 21:20:37 -04:00
// the alias is the same so we can just remove it
2019-04-07 21:14:59 -04:00
if ( oldAlias . AliasId ! = existingExactAlias . AliasId & & oldAlias . AliasId > 0 )
2019-04-02 21:20:37 -04:00
{
2019-04-12 23:25:18 -04:00
await context . Clients
. Where ( _client = > _client . CurrentAliasId = = oldAlias . AliasId )
. ForEachAsync ( _client = > _client . CurrentAliasId = existingExactAlias . AliasId ) ;
await context . SaveChangesAsync ( ) ;
2019-04-07 21:14:59 -04:00
entity . CurrentServer . Logger . WriteDebug ( $"[updatealias] {entity} has exact alias match, so we're going to try to remove aliasId {oldAlias.AliasId} with linkId {oldAlias.AliasId}" ) ;
2019-04-02 21:20:37 -04:00
context . Aliases . Remove ( oldAlias ) ;
await context . SaveChangesAsync ( ) ;
}
2019-01-02 19:32:39 -05:00
}
2018-11-25 21:00:36 -05:00
2019-01-02 19:32:39 -05:00
// theres no exact match, but they've played before with the GUID or IP
2019-04-05 14:34:03 -04:00
else
2019-01-02 19:32:39 -05:00
{
2019-04-07 21:14:59 -04:00
entity . CurrentServer . Logger . WriteDebug ( $"[updatealias] {entity} is using a new alias" ) ;
2018-12-31 21:52:19 -05:00
2019-04-05 14:34:03 -04:00
var newAlias = new EFAlias ( )
2019-01-02 19:32:39 -05:00
{
2019-04-05 14:34:03 -04:00
DateAdded = DateTime . UtcNow ,
IPAddress = ip ,
LinkId = newAliasLink . AliasLinkId ,
Name = name ,
Active = true ,
} ;
2018-12-31 21:52:19 -05:00
2019-04-05 14:34:03 -04:00
entity . CurrentAlias = newAlias ;
entity . CurrentAliasId = 0 ;
2019-01-02 19:32:39 -05:00
await context . SaveChangesAsync ( ) ;
}
2019-04-02 21:20:37 -04:00
}
2018-11-25 21:00:36 -05:00
2019-04-02 21:20:37 -04:00
/// <summary>
/// updates the permission level of the given target to the given permission level
/// </summary>
/// <param name="newPermission"></param>
/// <param name="temporalClient"></param>
/// <param name="origin"></param>
/// <param name="ctx"></param>
/// <returns></returns>
public async Task UpdateLevel ( Permission newPermission , EFClient temporalClient , EFClient origin )
{
using ( var ctx = new DatabaseContext ( ) )
2019-01-02 19:32:39 -05:00
{
2019-04-02 21:20:37 -04:00
var entity = await ctx . Clients
2019-05-02 23:33:38 -04:00
. Where ( _client = > _client . ClientId = = temporalClient . ClientId )
2019-04-02 21:20:37 -04:00
. FirstAsync ( ) ;
2019-04-05 14:34:03 -04:00
var oldPermission = entity . Level ;
entity . Level = newPermission ;
await ctx . SaveChangesAsync ( ) ;
#if DEBUG = = true
temporalClient . CurrentServer . Logger . WriteDebug ( $"Updated {temporalClient.ClientId} to {newPermission}" ) ;
#endif
2019-04-02 21:20:37 -04:00
// if their permission level has been changed to level that needs to be updated on all accounts
2019-04-05 14:34:03 -04:00
if ( ( oldPermission ! = newPermission ) & &
2019-04-02 21:20:37 -04:00
( newPermission = = Permission . Banned | |
newPermission = = Permission . Flagged | |
newPermission = = Permission . User ) )
2018-12-03 20:21:13 -05:00
{
2019-04-02 21:20:37 -04:00
var changeSvc = new ChangeHistoryService ( ) ;
2019-04-05 14:34:03 -04:00
//get all clients that have the same linkId
2019-04-02 21:20:37 -04:00
var iqMatchingClients = ctx . Clients
2019-04-05 14:34:03 -04:00
. Where ( _client = > _client . AliasLinkId = = entity . AliasLinkId ) ;
// make sure we don't select ourselves twice
//.Where(_client => _client.ClientId != temporalClient.ClientId);
2019-04-02 21:20:37 -04:00
// this updates the level for all the clients with the same LinkId
// only if their new level is flagged or banned
2019-04-14 11:55:05 -04:00
await iqMatchingClients . ForEachAsync ( _client = >
2019-04-02 21:20:37 -04:00
{
2019-04-05 14:34:03 -04:00
_client . Level = newPermission ;
#if DEBUG = = true
temporalClient . CurrentServer . Logger . WriteDebug ( $"Updated linked {_client.ClientId} to {newPermission}" ) ;
#endif
} ) ;
2019-04-02 21:20:37 -04:00
2019-04-05 14:34:03 -04:00
await ctx . SaveChangesAsync ( ) ;
}
2017-11-25 20:29:58 -05:00
}
2019-04-02 21:20:37 -04:00
temporalClient . Level = newPermission ;
2017-11-25 20:29:58 -05:00
}
public async Task < EFClient > Delete ( EFClient entity )
{
2017-11-29 19:35:50 -05:00
using ( var context = new DatabaseContext ( ) )
2017-11-25 20:29:58 -05:00
{
2017-11-29 19:35:50 -05:00
var client = context . Clients
. Single ( e = > e . ClientId = = entity . ClientId ) ;
2017-11-25 20:29:58 -05:00
entity . Active = false ;
context . Entry ( entity ) . State = EntityState . Modified ;
await context . SaveChangesAsync ( ) ;
return entity ;
}
}
2019-06-11 09:00:14 -04:00
public Task < IList < EFClient > > Find ( Func < EFClient , bool > e )
2017-11-25 20:29:58 -05:00
{
2019-06-11 09:00:14 -04:00
throw new NotImplementedException ( ) ;
2017-11-25 20:29:58 -05:00
}
public async Task < EFClient > Get ( int entityID )
{
2018-09-13 15:34:42 -04:00
using ( var context = new DatabaseContext ( true ) )
2018-02-10 23:33:42 -05:00
{
2018-05-14 13:55:10 -04:00
var iqClient = from client in context . Clients
. Include ( c = > c . CurrentAlias )
. Include ( c = > c . AliasLink . Children )
2018-06-02 00:48:10 -04:00
. Include ( c = > c . Meta )
2018-05-14 13:55:10 -04:00
where client . ClientId = = entityID
select new
{
Client = client ,
LinkedAccounts = ( from linkedClient in context . Clients
2018-06-07 22:19:12 -04:00
where client . AliasLinkId = = linkedClient . AliasLinkId
select new
{
linkedClient . ClientId ,
linkedClient . NetworkId
} )
2018-05-14 13:55:10 -04:00
} ;
2018-09-13 15:34:42 -04:00
#if DEBUG = = true
var clientSql = iqClient . ToSql ( ) ;
#endif
2018-05-14 13:55:10 -04:00
var foundClient = await iqClient . FirstOrDefaultAsync ( ) ;
2018-05-24 15:48:57 -04:00
if ( foundClient = = null )
2018-11-25 21:00:36 -05:00
{
2018-05-24 15:48:57 -04:00
return null ;
2018-11-25 21:00:36 -05:00
}
2018-05-24 15:48:57 -04:00
2018-05-14 13:55:10 -04:00
foundClient . Client . LinkedAccounts = new Dictionary < int , long > ( ) ;
// todo: find out the best way to do this
// I'm doing this here because I don't know the best way to have multiple awaits in the query
foreach ( var linked in foundClient . LinkedAccounts )
2018-11-25 21:00:36 -05:00
{
2018-05-14 13:55:10 -04:00
foundClient . Client . LinkedAccounts . Add ( linked . ClientId , linked . NetworkId ) ;
2018-11-25 21:00:36 -05:00
}
2018-05-14 13:55:10 -04:00
return foundClient . Client ;
2018-02-10 23:33:42 -05:00
}
2017-11-25 20:29:58 -05:00
}
2018-09-13 15:34:42 -04:00
private static readonly Func < DatabaseContext , long , Task < EFClient > > _getUniqueQuery =
EF . CompileAsyncQuery ( ( DatabaseContext context , long networkId ) = >
context . Clients
. Include ( c = > c . CurrentAlias )
. Include ( c = > c . AliasLink . Children )
2018-12-29 13:43:40 -05:00
. Include ( c = > c . ReceivedPenalties )
2018-09-13 15:34:42 -04:00
. FirstOrDefault ( c = > c . NetworkId = = networkId )
) ;
2018-02-10 23:33:42 -05:00
public async Task < EFClient > GetUnique ( long entityAttribute )
2017-11-25 20:29:58 -05:00
{
2018-09-13 15:34:42 -04:00
using ( var context = new DatabaseContext ( true ) )
2017-11-25 20:29:58 -05:00
{
2018-09-13 15:34:42 -04:00
return await _getUniqueQuery ( context , entityAttribute ) ;
2017-11-25 20:29:58 -05:00
}
}
2019-04-02 21:20:37 -04:00
public async Task UpdateAlias ( EFClient temporalClient )
2017-11-25 20:29:58 -05:00
{
2017-11-29 19:35:50 -05:00
using ( var context = new DatabaseContext ( ) )
2017-11-25 20:29:58 -05:00
{
2019-04-02 21:20:37 -04:00
var entity = context . Clients
2017-11-29 19:35:50 -05:00
. Include ( c = > c . AliasLink )
2018-02-07 00:19:06 -05:00
. Include ( c = > c . CurrentAlias )
2019-04-02 21:20:37 -04:00
. First ( e = > e . ClientId = = temporalClient . ClientId ) ;
2018-09-11 15:28:37 -04:00
2019-04-02 21:20:37 -04:00
entity . CurrentServer = temporalClient . CurrentServer ;
2019-01-02 19:32:39 -05:00
2019-04-02 21:20:37 -04:00
await UpdateAlias ( temporalClient . Name , temporalClient . IPAddress , entity , context ) ;
2019-01-02 19:32:39 -05:00
2019-04-02 21:20:37 -04:00
temporalClient . CurrentAlias = entity . CurrentAlias ;
temporalClient . CurrentAliasId = entity . CurrentAliasId ;
temporalClient . AliasLink = entity . AliasLink ;
temporalClient . AliasLinkId = entity . AliasLinkId ;
2019-01-02 19:32:39 -05:00
}
}
2019-04-02 21:20:37 -04:00
public async Task < EFClient > Update ( EFClient temporalClient )
2019-01-02 19:32:39 -05:00
{
using ( var context = new DatabaseContext ( ) )
{
// grab the context version of the entity
2019-04-02 21:20:37 -04:00
var entity = context . Clients
. First ( client = > client . ClientId = = temporalClient . ClientId ) ;
2019-01-02 19:32:39 -05:00
2019-06-13 20:10:08 -04:00
if ( temporalClient . LastConnection > entity . LastConnection )
{
entity . LastConnection = temporalClient . LastConnection ;
}
if ( temporalClient . Connections > entity . Connections )
2019-06-12 11:27:15 -04:00
{
2019-06-13 20:10:08 -04:00
entity . Connections = temporalClient . Connections ;
2019-06-12 11:27:15 -04:00
}
2019-04-02 21:20:37 -04:00
entity . Masked = temporalClient . Masked ;
2019-06-13 20:10:08 -04:00
if ( temporalClient . TotalConnectionTime > entity . TotalConnectionTime )
{
entity . TotalConnectionTime = temporalClient . TotalConnectionTime ;
}
if ( temporalClient . Password ! = null )
{
entity . Password = temporalClient . Password ;
}
if ( temporalClient . PasswordSalt ! = null )
{
entity . PasswordSalt = temporalClient . PasswordSalt ;
}
2017-11-29 19:35:50 -05:00
// update in database
2017-11-25 20:29:58 -05:00
await context . SaveChangesAsync ( ) ;
2019-04-02 21:20:37 -04:00
return entity ;
2017-11-25 20:29:58 -05:00
}
}
2018-09-16 16:34:16 -04:00
#region ServiceSpecific
2017-11-25 20:29:58 -05:00
public async Task < IList < EFClient > > GetOwners ( )
{
2017-11-29 19:35:50 -05:00
using ( var context = new DatabaseContext ( ) )
2018-11-25 21:00:36 -05:00
{
2017-11-29 19:35:50 -05:00
return await context . Clients
2018-11-05 22:01:29 -05:00
. Where ( c = > c . Level = = Permission . Owner )
2017-11-29 19:35:50 -05:00
. ToListAsync ( ) ;
2018-11-25 21:00:36 -05:00
}
2017-11-25 20:29:58 -05:00
}
2019-03-24 22:34:20 -04:00
/// <summary>
/// retrieves the number of owners
/// (client level is owner)
/// </summary>
/// <returns></returns>
public async Task < int > GetOwnerCount ( )
{
using ( var ctx = new DatabaseContext ( true ) )
{
2019-06-11 09:00:14 -04:00
return await ctx . Clients
2019-03-24 22:34:20 -04:00
. CountAsync ( _client = > _client . Level = = Permission . Owner ) ;
}
}
2019-05-03 21:13:51 -04:00
public async Task < List < EFClient > > GetPrivilegedClients ( bool includeName = true )
2018-02-16 23:24:03 -05:00
{
2018-09-13 15:34:42 -04:00
using ( var context = new DatabaseContext ( disableTracking : true ) )
2018-02-16 23:24:03 -05:00
{
2019-03-24 22:34:20 -04:00
var iqClients = from client in context . Clients . AsNoTracking ( )
2018-11-05 22:01:29 -05:00
where client . Level > = Permission . Trusted
2018-09-13 15:34:42 -04:00
where client . Active
2018-11-25 21:00:36 -05:00
select new EFClient ( )
2018-09-13 15:34:42 -04:00
{
2018-11-25 22:11:55 -05:00
AliasLinkId = client . AliasLinkId ,
2018-11-25 21:00:36 -05:00
CurrentAlias = client . CurrentAlias ,
2018-09-13 15:34:42 -04:00
ClientId = client . ClientId ,
2018-11-25 21:00:36 -05:00
Level = client . Level ,
Password = client . Password ,
2019-01-03 15:39:22 -05:00
PasswordSalt = client . PasswordSalt ,
2019-03-25 22:12:16 -04:00
NetworkId = client . NetworkId ,
LastConnection = client . LastConnection
2018-09-13 15:34:42 -04:00
} ;
#if DEBUG = = true
var clientsSql = iqClients . ToSql ( ) ;
#endif
2018-05-14 13:55:10 -04:00
return await iqClients . ToListAsync ( ) ;
2018-02-11 20:17:20 -05:00
}
2017-11-25 20:29:58 -05:00
}
2019-04-25 22:05:35 -04:00
public async Task < IList < PlayerInfo > > FindClientsByIdentifier ( string identifier )
2018-02-11 20:17:20 -05:00
{
2019-04-14 11:55:05 -04:00
if ( identifier ? . Length < 3 )
2018-10-15 20:51:04 -04:00
{
2019-04-25 22:05:35 -04:00
return new List < PlayerInfo > ( ) ;
2018-10-15 20:51:04 -04:00
}
2018-04-21 18:18:20 -04:00
2018-09-16 16:34:16 -04:00
using ( var context = new DatabaseContext ( disableTracking : true ) )
2018-09-11 15:28:37 -04:00
{
2019-05-03 21:13:51 -04:00
long? networkId = null ;
try
{
networkId = identifier . ConvertGuidToLong ( ) ;
}
catch { }
2018-12-16 22:16:56 -05:00
int? ipAddress = identifier . ConvertToIP ( ) ;
2018-06-07 22:19:12 -04:00
2019-04-25 22:05:35 -04:00
IQueryable < EFAlias > iqLinkIds = context . Aliases . Where ( _alias = > _alias . Active ) ;
2018-09-11 15:28:37 -04:00
2019-04-25 22:05:35 -04:00
// we want to query for the IP ADdress
if ( ipAddress ! = null )
{
iqLinkIds = iqLinkIds . Where ( _alias = > _alias . IPAddress = = ipAddress ) ;
}
// want to find them by name (wildcard)
else
{
2019-05-08 21:34:17 -04:00
iqLinkIds = iqLinkIds . Where ( _alias = > EF . Functions . Like ( _alias . Name . ToLower ( ) , $"%{identifier.ToLower()}%" ) ) ;
2019-04-25 22:05:35 -04:00
}
var linkIds = await iqLinkIds
. Select ( _alias = > _alias . LinkId )
. ToListAsync ( ) ;
2018-09-11 15:28:37 -04:00
2019-04-25 22:05:35 -04:00
// get all the clients that match the alias link or the network id
2018-09-11 15:28:37 -04:00
var iqClients = context . Clients
2019-04-25 22:05:35 -04:00
. Where ( _client = > _client . Active ) ;
2018-09-11 15:28:37 -04:00
2019-05-03 21:13:51 -04:00
if ( networkId . HasValue )
2019-04-25 22:05:35 -04:00
{
2019-05-03 21:13:51 -04:00
iqClients = iqClients . Where ( _client = > networkId . Value = = _client . NetworkId ) ;
2019-04-25 22:05:35 -04:00
}
2019-05-03 21:13:51 -04:00
2019-04-25 22:05:35 -04:00
else
{
iqClients = iqClients . Where ( _client = > linkIds . Contains ( _client . AliasLinkId ) ) ;
}
2019-06-11 09:00:14 -04:00
2019-04-25 22:05:35 -04:00
// we want to project our results
var iqClientProjection = iqClients . OrderByDescending ( _client = > _client . LastConnection )
. Select ( _client = > new PlayerInfo ( )
{
Name = _client . CurrentAlias . Name ,
LevelInt = ( int ) _client . Level ,
LastConnection = _client . LastConnection ,
ClientId = _client . ClientId ,
} ) ;
2018-09-11 15:28:37 -04:00
#if DEBUG = = true
var iqClientsSql = iqClients . ToSql ( ) ;
#endif
2019-04-25 22:05:35 -04:00
var clients = await iqClientProjection . ToListAsync ( ) ;
2019-06-11 09:00:14 -04:00
2019-04-25 22:05:35 -04:00
// this is so we don't try to evaluate this in the linq to entities query
foreach ( var client in clients )
{
client . Level = ( ( Permission ) client . LevelInt ) . ToLocalizedLevelName ( ) ;
}
2018-02-23 02:06:13 -05:00
2019-04-25 22:05:35 -04:00
return clients ;
2018-02-23 02:06:13 -05:00
}
}
2017-11-25 20:29:58 -05:00
public async Task < int > GetTotalClientsAsync ( )
{
2018-09-16 16:34:16 -04:00
using ( var context = new DatabaseContext ( true ) )
2018-11-25 21:00:36 -05:00
{
2017-11-29 19:35:50 -05:00
return await context . Clients
. CountAsync ( ) ;
2018-11-25 21:00:36 -05:00
}
2017-11-25 20:29:58 -05:00
}
2019-07-16 16:27:19 -04:00
2019-07-24 11:36:37 -04:00
/// <summary>
/// Returns the number of clients seen today
/// </summary>
/// <returns></returns>
public async Task < int > GetRecentClientCount ( )
{
using ( var context = new DatabaseContext ( true ) )
{
var startOfPeriod = DateTime . UtcNow . AddHours ( - 24 ) ;
var iqQuery = context . Clients . Where ( _client = > _client . LastConnection > = startOfPeriod ) ;
#if DEBUG
string sql = iqQuery . ToSql ( ) ;
#endif
return await iqQuery . CountAsync ( ) ;
}
}
2019-07-16 16:27:19 -04:00
/// <summary>
/// gets the 10 most recently added clients to IW4MAdmin
/// </summary>
/// <returns></returns>
public async Task < IList < PlayerInfo > > GetRecentClients ( )
{
using ( var context = new DatabaseContext ( true ) )
{
var iqClients = context . Clients
. Where ( _client = > _client . CurrentAlias . IPAddress ! = null )
. Select ( _client = > new PlayerInfo ( )
{
ClientId = _client . ClientId ,
Name = _client . CurrentAlias . Name ,
IPAddress = _client . CurrentAlias . IPAddress . ConvertIPtoString ( ) ,
LastConnection = _client . LastConnection
} )
. OrderByDescending ( _client = > _client . ClientId )
. Take ( 10 ) ;
#if DEBUG
var sql = iqClients . ToSql ( ) ;
#endif
return await iqClients . ToListAsync ( ) ;
}
}
2018-09-16 16:34:16 -04:00
#endregion
2017-11-25 20:29:58 -05:00
}
}