Example #1
0
        public async Task Seed()
        {
            context.Database.Migrate();

            if (context.AliasLinks.Count() == 0)
            {
                var link = new EFAliasLink();

                context.Clients.Add(new EFClient()
                {
                    ClientId        = 1,
                    Active          = false,
                    Connections     = 0,
                    FirstConnection = DateTime.UtcNow,
                    LastConnection  = DateTime.UtcNow,
                    Level           = Permission.Console,
                    Masked          = true,
                    NetworkId       = 0,
                    AliasLink       = link,
                    CurrentAlias    = new EFAlias()
                    {
                        Link      = link,
                        Active    = true,
                        DateAdded = DateTime.UtcNow,
                        Name      = "IW4MAdmin",
                    },
                });

                await context.SaveChangesAsync();
            }
        }
Example #2
0
        public static async Task Seed(IDatabaseContextFactory contextFactory, CancellationToken token)
        {
            await using var context = contextFactory.CreateContext();
            var strategy = context.Database.CreateExecutionStrategy();
            await strategy.ExecuteAsync(async() =>
            {
                await context.Database.MigrateAsync(token);
            });

            if (!await context.AliasLinks.AnyAsync(token))
            {
                var link = new EFAliasLink();

                context.Clients.Add(new EFClient()
                {
                    Active          = false,
                    Connections     = 0,
                    FirstConnection = DateTime.UtcNow,
                    LastConnection  = DateTime.UtcNow,
                    Level           = EFClient.Permission.Console,
                    Masked          = true,
                    NetworkId       = 0,
                    AliasLink       = link,
                    CurrentAlias    = new EFAlias()
                    {
                        Link      = link,
                        Active    = true,
                        DateAdded = DateTime.UtcNow,
                        Name      = "IW4MAdmin",
                    },
                });

                await context.SaveChangesAsync(token);
            }
        }
Example #3
0
        public async Task <EFClient> Create(EFClient entity)
        {
            using (var context = new DatabaseContext())
            {
                bool hasExistingAlias = false;
                // get all aliases by IP
                var aliases = await context.Aliases
                              .Include(a => a.Link)
                              .Where(a => a.IPAddress == entity.IPAddress)
                              .ToListAsync();

                // see if they have a matching IP + Name but new NetworkId
                var existingAlias = aliases.FirstOrDefault(a => a.Name == entity.Name);
                // if existing alias matches link them
                EFAliasLink aliasLink = existingAlias?.Link;
                // if no exact matches find the first IP that matches
                aliasLink = aliasLink ?? aliases.FirstOrDefault()?.Link;
                // if no exact or IP matches, create new link
                aliasLink = aliasLink ?? new EFAliasLink()
                {
                    Active = true,
                };

                // this has to be set here because we can't evalute it properly later
                hasExistingAlias = existingAlias != null;

                // if no existing alias create new alias
                existingAlias = existingAlias ?? new EFAlias()
                {
                    Active    = true,
                    DateAdded = DateTime.UtcNow,
                    IPAddress = entity.IPAddress,
                    Link      = aliasLink,
                    Name      = entity.Name,
                };

                var client = new EFClient()
                {
                    Active = true,
                    // set the level to the level of the existing client if they have the same IP + Name but new NetworkId
                    // fixme: issues?
                    Level = hasExistingAlias ?
                            context.Clients.First(c => c.AliasLinkId == existingAlias.LinkId).Level :
                            Player.Permission.User,
                    FirstConnection = DateTime.UtcNow,
                    Connections     = 1,
                    LastConnection  = DateTime.UtcNow,
                    Masked          = false,
                    NetworkId       = entity.NetworkId,
                    AliasLink       = aliasLink,
                    CurrentAlias    = existingAlias
                };

                context.Clients.Add(client);
                await context.SaveChangesAsync();

                return(client);
            }
        }
Example #4
0
        private async Task <EFClient> HandleNewCreate(EFClient entity)
        {
            await using var context = _contextFactory.CreateContext(true);
            using (LogContext.PushProperty("Server", entity.CurrentServer?.ToString()))
            {
                var existingAlias = await context.Aliases
                                    .Select(alias => new { alias.AliasId, alias.LinkId, alias.IPAddress, alias.Name })
                                    .Where(alias => alias.IPAddress != null && alias.IPAddress == entity.IPAddress &&
                                           alias.Name == entity.Name)
                                    .FirstOrDefaultAsync();

                var client = new EFClient
                {
                    Level           = Permission.User,
                    FirstConnection = DateTime.UtcNow,
                    LastConnection  = DateTime.UtcNow,
                    NetworkId       = entity.NetworkId
                };

                if (existingAlias == null)
                {
                    _logger.LogDebug("[{Method}] creating new Link and Alias for {Entity}", nameof(HandleNewCreate), entity.ToString());
                    var link  = new EFAliasLink();
                    var alias = new EFAlias
                    {
                        Name           = entity.Name,
                        SearchableName = entity.Name.StripColors().ToLower(),
                        DateAdded      = DateTime.UtcNow,
                        IPAddress      = entity.IPAddress,
                        Link           = link
                    };
                    client.CurrentAlias = alias;
                    client.AliasLink    = link;
                }

                else
                {
                    _logger.LogDebug("[{Method}] associating new GUID {Guid} with new exact alias match with linkId {LinkId} for {Entity}",
                                     nameof(HandleNewCreate), entity.GuidString, existingAlias.LinkId, entity.ToString());

                    var alias = new EFAlias
                    {
                        Name           = existingAlias.Name,
                        SearchableName = entity.Name.StripColors().ToLower(),
                        DateAdded      = DateTime.UtcNow,
                        IPAddress      = entity.IPAddress,
                        LinkId         = existingAlias.LinkId
                    };
                    client.CurrentAlias = alias;
                    client.AliasLinkId  = existingAlias.LinkId;
                }

                context.Clients.Add(client);
                await context.SaveChangesAsync();

                return(client);
            }
        }
Example #5
0
        public static void ImportClients(IList <Player> clients)
        {
            DatabaseContext context = null;

            try
            {
                context = new DatabaseContext();
                context.Configuration.AutoDetectChangesEnabled = false;
                context.Configuration.LazyLoadingEnabled       = false;
                context.Configuration.ProxyCreationEnabled     = false;

                int count = 0;
                foreach (var entityToInsert in clients)
                {
                    ++count;

                    var link = new EFAliasLink()
                    {
                        Active = true
                    };

                    var alias = new EFAlias()
                    {
                        Active    = true,
                        DateAdded = entityToInsert.LastConnection,
                        IPAddress = entityToInsert.IPAddress,
                        Link      = link,
                        Name      = entityToInsert.Name,
                    };

                    var client = new EFClient()
                    {
                        Active              = true,
                        AliasLink           = link,
                        Connections         = entityToInsert.Connections,
                        CurrentAlias        = alias,
                        FirstConnection     = entityToInsert.LastConnection,
                        Level               = entityToInsert.Level,
                        LastConnection      = entityToInsert.LastConnection,
                        TotalConnectionTime = entityToInsert.TotalConnectionTime,
                        Masked              = entityToInsert.Masked,
                        NetworkId           = entityToInsert.NetworkId
                    };

                    context = AddClient(context, client, count, 1000, true);
                }

                context.SaveChanges();
            }
            finally
            {
                if (context != null)
                {
                    context.Dispose();
                }
            }
        }
Example #6
0
        public async Task <EFAliasLink> CreateLink(EFAliasLink link)
        {
            using (var context = new DatabaseContext())
            {
                context.AliasLinks.Add(link);
                await context.SaveChangesAsync();

                return(link);
            }
        }
Example #7
0
        /// <summary>
        /// Unlinks shared GUID account into its own separate account
        /// </summary>
        /// <param name="clientId"></param>
        /// <returns></returns>
        public async Task UnlinkClient(int clientId)
        {
            await using var ctx = _contextFactory.CreateContext();
            var newLink = new EFAliasLink()
            {
                Active = true
            };

            ctx.AliasLinks.Add(newLink);
            await ctx.SaveChangesAsync();

            var client = await ctx.Clients.Include(_client => _client.CurrentAlias)
                         .FirstAsync(_client => _client.ClientId == clientId);

            client.AliasLinkId = newLink.AliasLinkId;
            client.Level       = Permission.User;

            await ctx.Aliases.Where(_alias => _alias.IPAddress == client.CurrentAlias.IPAddress && _alias.IPAddress != null)
            .ForEachAsync(_alias => _alias.LinkId = newLink.AliasLinkId);

            if (!_appConfig.EnableImplicitAccountLinking)
            {
                var clientIdsByIp = await ctx.Clients.Where(c =>
                                                            client.CurrentAlias.IPAddress != null &&
                                                            c.CurrentAlias.IPAddress == client.CurrentAlias.IPAddress)
                                    .Select(c => c.ClientId)
                                    .ToListAsync();

                await ctx.Penalties.Where(penalty =>
                                          clientIdsByIp.Contains(penalty.OffenderId) &&
                                          new[]
                {
                    EFPenalty.PenaltyType.Ban, EFPenalty.PenaltyType.TempBan, EFPenalty.PenaltyType.Flag
                }.Contains(penalty.Type) &&
                                          penalty.Expires == null)
                .ForEachAsync(penalty => penalty.Expires = DateTime.UtcNow);
            }

            await ctx.SaveChangesAsync();
        }
Example #8
0
        public async Task <EFClient> Create(EFClient entity)
        {
            using (var context = new DatabaseContext())
            {
                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)
                    {
                        entity.CurrentServer.Logger.WriteDebug($"[create] client with new GUID {entity} has existing link {existingAlias.LinkId}");

                        linkId = existingAlias.LinkId;
                        if (existingAlias.Name == entity.Name)
                        {
                            entity.CurrentServer.Logger.WriteDebug($"[create] client with new GUID {entity} has existing alias {existingAlias.AliasId}");
                            aliasId = existingAlias.AliasId;
                        }
                    }
                }

                var client = new EFClient()
                {
                    Level           = Permission.User,
                    FirstConnection = DateTime.UtcNow,
                    LastConnection  = DateTime.UtcNow,
                    NetworkId       = entity.NetworkId
                };

                context.Clients.Add(client);

                // they're just using a new GUID
                if (aliasId.HasValue)
                {
                    entity.CurrentServer.Logger.WriteDebug($"[create] setting {entity}'s alias id and linkid to ({aliasId.Value}, {linkId.Value})");
                    client.CurrentAliasId = aliasId.Value;
                    client.AliasLinkId    = linkId.Value;
                }

                // link was found but they don't have an exact alias
                else if (!aliasId.HasValue && linkId.HasValue)
                {
                    entity.CurrentServer.Logger.WriteDebug($"[create] setting {entity}'s linkid to {linkId.Value}, but creating new alias");
                    client.AliasLinkId  = linkId.Value;
                    client.CurrentAlias = new EFAlias()
                    {
                        Name      = entity.Name,
                        DateAdded = DateTime.UtcNow,
                        IPAddress = entity.IPAddress,
                        LinkId    = linkId.Value
                    };
                }

                // brand new players (supposedly)
                else
                {
                    entity.CurrentServer.Logger.WriteDebug($"[create] creating new Link and Alias for {entity}");
                    var link  = new EFAliasLink();
                    var alias = new EFAlias()
                    {
                        Name      = entity.Name,
                        DateAdded = DateTime.UtcNow,
                        IPAddress = entity.IPAddress,
                        Link      = link
                    };

                    link.Children.Add(alias);

                    client.AliasLink    = link;
                    client.CurrentAlias = alias;
                }

                await context.SaveChangesAsync();

                return(client);
            }
        }
Example #9
0
        public async Task <EFClient> Create(EFClient entity)
        {
            entity.Name = entity.Name.CapClientName(EFAlias.MAX_NAME_LENGTH);

            if (!_appConfig.EnableImplicitAccountLinking)
            {
                return(await HandleNewCreate(entity));
            }

            await using var context = _contextFactory.CreateContext(true);
            using (LogContext.PushProperty("Server", entity?.CurrentServer?.ToString()))
            {
                int?linkId  = null;
                int?aliasId = null;

                if (entity.IPAddress != null)
                {
                    var existingAliases = await context.Aliases
                                          .Select(_alias => new { _alias.AliasId, _alias.LinkId, _alias.IPAddress, _alias.Name })
                                          .Where(_alias => _alias.IPAddress == entity.IPAddress)
                                          .ToListAsync();

                    if (existingAliases.Count > 0)
                    {
                        linkId = existingAliases.OrderBy(_alias => _alias.LinkId).First().LinkId;

                        _logger.LogDebug("[create] client with new GUID {entity} has existing link {linkId}", entity.ToString(), linkId);

                        var existingExactAlias = existingAliases.FirstOrDefault(_alias => _alias.Name == entity.Name);

                        if (existingExactAlias != null)
                        {
                            _logger.LogDebug("[create] client with new GUID {entity} has existing alias {aliasId}", entity.ToString(), existingExactAlias.AliasId);
                            aliasId = existingExactAlias.AliasId;
                        }
                    }
                }

                var client = new EFClient()
                {
                    Level           = Permission.User,
                    FirstConnection = DateTime.UtcNow,
                    LastConnection  = DateTime.UtcNow,
                    NetworkId       = entity.NetworkId
                };

                _logger.LogDebug("[create] adding {entity} to context", entity.ToString());


                // they're just using a new GUID
                if (aliasId.HasValue)
                {
                    _logger.LogDebug("[create] setting {entity}'s alias id and linkid to ({aliasId}, {linkId})", entity.ToString(), aliasId, linkId);
                    client.CurrentAliasId = aliasId.Value;
                    client.AliasLinkId    = linkId.Value;
                }

                // link was found but they don't have an exact alias
                else if (!aliasId.HasValue && linkId.HasValue)
                {
                    _logger.LogDebug("[create] setting {entity}'s linkid to {linkId}, but creating new alias", entity.ToString(), linkId);
                    client.AliasLinkId  = linkId.Value;
                    client.CurrentAlias = new EFAlias()
                    {
                        Name           = entity.Name,
                        SearchableName = entity.Name.StripColors().ToLower(),
                        DateAdded      = DateTime.UtcNow,
                        IPAddress      = entity.IPAddress,
                        LinkId         = linkId.Value
                    };
                }

                // brand new players (supposedly)
                else
                {
                    _logger.LogDebug("[create] creating new Link and Alias for {entity}", entity.ToString());
                    var link  = new EFAliasLink();
                    var alias = new EFAlias()
                    {
                        Name           = entity.Name,
                        SearchableName = entity.Name.StripColors().ToLower(),
                        DateAdded      = DateTime.UtcNow,
                        IPAddress      = entity.IPAddress,
                        Link           = link
                    };

                    client.AliasLink    = link;
                    client.CurrentAlias = alias;
                }

                context.Clients.Add(client);
                await context.SaveChangesAsync();

                return(client);
            }
        }