Example #1
0
        private void HandleDisconnectCalculations(EFClient client, HitState state)
        {
            // todo: this not added to states fast connect/disconnect
            var serverStats = state.Hits.FirstOrDefault(stat =>
                                                        stat.ServerId == state.Server.ServerId && stat.WeaponId == null &&
                                                        stat.WeaponAttachmentComboId == null && stat.HitLocationId == null && stat.MeansOfDeathId == null);

            if (serverStats == null)
            {
                _logger.LogWarning("No server hits were found for {serverId} on disconnect for {client}",
                                   state.Server.ServerId, client.ToString());
                return;
            }

            var aggregate = state.Hits.FirstOrDefault(stat => stat.WeaponId == null &&
                                                      stat.WeaponAttachmentComboId == null &&
                                                      stat.HitLocationId == null &&
                                                      stat.MeansOfDeathId == null &&
                                                      stat.ServerId == null);

            if (aggregate == null)
            {
                _logger.LogWarning("No aggregate found for {serverId} on disconnect for {client}",
                                   state.Server.ServerId, client.ToString());
                return;
            }

            var sessionScores = client.GetAdditionalProperty <List <(int, DateTime)> >(SessionScores);

            if (sessionScores == null)
            {
                _logger.LogWarning("No session scores available for {Client}", client.ToString());
                return;
            }

            foreach (var stat in new[] { serverStats, aggregate })
            {
                stat.Score ??= 0;

                if (sessionScores.Count == 0)
                {
                    stat.Score += client.Score > 0 ? client.Score : client.GetAdditionalProperty <int?>(Helpers.StatManager.ESTIMATED_SCORE) ?? 0 * 50;
                }

                else
                {
                    stat.Score += sessionScores.Sum(item => item.Item1) +
                                  (sessionScores.Last().Item1 == client.Score &&
                                   (DateTime.Now - sessionScores.Last().Item2).TotalMinutes < 1
                                      ? 0
                                      : client.Score);
                }
            }
        }
Example #2
0
        private void RunCalculation(EFClientHitStatistic clientHit, HitInfo hitInfo, HitState hitState)
        {
            if (hitInfo.HitType == HitType.Kill || hitInfo.HitType == HitType.Damage)
            {
                if (clientHit.WeaponId != null) // we only want to calculate usage time for weapons
                {
                    var timeElapsed  = DateTime.Now - hitState.LastUsage;
                    var isSameWeapon = clientHit.WeaponId == hitState.LastWeaponId;

                    clientHit.UsageSeconds ??= 60;

                    if (timeElapsed.HasValue && timeElapsed <= _maxActiveTime)
                    {
                        clientHit.UsageSeconds
                            += // if it's the same weapon we can count the entire elapsed time
                               // otherwise we split it to make a best guess
                               (int)Math.Round(timeElapsed.Value.TotalSeconds / (isSameWeapon ? 1.0 : 2.0));
                    }

                    hitState.LastUsage = DateTime.Now;
                }

                clientHit.DamageInflicted += hitInfo.Damage;
                clientHit.HitCount++;
            }

            if (hitInfo.HitType == HitType.Kill)
            {
                clientHit.KillCount++;
            }

            if (hitInfo.HitType == HitType.WasKilled || hitInfo.HitType == HitType.WasDamaged ||
                hitInfo.HitType == HitType.Suicide)
            {
                clientHit.ReceivedHitCount++;
                clientHit.DamageReceived += hitInfo.Damage;
            }

            if (hitInfo.HitType == HitType.WasKilled)
            {
                clientHit.DeathCount++;
            }
        }
Example #3
0
        private async Task UpdateClientStatistics(int clientId, HitState locState = null)
        {
            if (!_clientHitStatistics.ContainsKey(clientId) && locState == null)
            {
                _logger.LogError("No {statsName} found for id {id}", nameof(EFClientHitStatistic), clientId);
                return;
            }

            var state = locState ?? _clientHitStatistics[clientId];

            try
            {
                await using var context = _contextFactory.CreateContext();
                context.Set <EFClientHitStatistic>().UpdateRange(state.Hits);
                await context.SaveChangesAsync();
            }

            catch (Exception ex)
            {
                _logger.LogError(ex, "Could not update hit location stats for id {id}", clientId);
            }
        }