<commit_before>﻿using System.Collections.Generic;
using System.Linq;
using Data;
using Tera.Game;

namespace DamageMeter.Database.Structures
{
    public class Skills
    {
        private readonly Dictionary<string, object> _caching = new Dictionary<string, object>();

        public Skills(Dictionary<Entity, Dictionary<Entity, List<Skill>>> sourceTargetSkill, Dictionary<Entity, Dictionary<Entity, List<Skill>>> targetSourceSkill,
            Dictionary<Entity, Dictionary<Entity, Dictionary<int, List<Skill>>>> sourceTargetIdSkill, Dictionary<Entity, Dictionary<int, List<Skill>>> sourceIdSkill)
        {
            SourceTargetSkill = sourceTargetSkill;
            TargetSourceSkill = targetSourceSkill;
            SourceIdSkill = sourceIdSkill;
            SourceTargetIdSkill = sourceTargetIdSkill;
        }


        private Dictionary<Entity, Dictionary<Entity, List<Skill>>> SourceTargetSkill { get; }
        private Dictionary<Entity, Dictionary<Entity, List<Skill>>> TargetSourceSkill { get; }
        private Dictionary<Entity, Dictionary<int, List<Skill>>> SourceIdSkill { get; }
        private Dictionary<Entity, Dictionary<Entity, Dictionary<int, List<Skill>>>> SourceTargetIdSkill { get; }

        public List<Player> GetPlayers()
        {
            return SourceIdSkill.Keys.Where(x => x is UserEntity).Select(x=>NetworkController.Instance.PlayerTracker.Get(((UserEntity)x).ServerId, ((UserEntity)x).PlayerId)).ToList();
        }

        public long DamageReceived(Entity target, Entity source, bool timed)
        {
            var sourceString = source?.Id.ToString() ?? "";
            var key = "damage_received/" + target + "/" + sourceString + "/" + timed;
            if (_caching.ContainsKey(key)) { return (long) _caching[key]; }
            IEnumerable<long> result = new List<long>();

            if (TargetSourceSkill.ContainsKey(target))
            {
                if (!timed && source != null)
                {
                    if (TargetSourceSkill[target].ContainsKey(source))
                    {
                        result = from skills in TargetSourceSkill[target][source] where skills.Type == Database.Type.Damage select skills.Amount;
                    }
                }
                else { result = from skills in TargetSourceSkill[target].Values from skill in skills where skill.Type == Database.Type.Damage select skill.Amount; }
            }

            var sum = result.Sum();
            _caching.Add(key, sum);
            return sum;
        }

        public int HitsReceived(Entity target, Entity source, bool timed)
        {
            var sourceString = source?.Id.ToString() ?? "";
            var key = "hits_received/" + target + "/" + sourceString + "/" + timed;
            if (_caching.ContainsKey(key)) { return (int) _caching[key]; }

            IEnumerable<Skill> result = new List<Skill>();
            if (TargetSourceSkill.ContainsKey(target))
            {
                if (!timed && source != null)
                {
                    if (TargetSourceSkill[target].ContainsKey(source))
                    {
                        result = from skills in TargetSourceSkill[target][source] where skills.Type == Database.Type.Damage select skills;
                    }
                }
                else { result = from skills in TargetSourceSkill[target].Values from skill in skills where skill.Type == Database.Type.Damage select skill; }
            }

            var count = result.Count();
            _caching.Add(key, count);
            return count;
        }

        public long BiggestCrit(Entity source, Entity target, bool timed)
        {
            var targetString = target?.Id.ToString() ?? "";
            var key = "biggest_crit/" + source + "/" + targetString + "/" + timed;
            if (_caching.ContainsKey(key)) { return (long) _caching[key]; }

            IEnumerable<long> result;

            if (timed || target == null)
            {
                result = from skills in SourceTargetSkill[source].Values
                    from skill in skills
                    where skill.Type == Database.Type.Damage
                    where skill.Critic
                    select skill.Amount;
            }
            else { result = from skills in SourceTargetSkill[source][target] where skills.Type == Database.Type.Damage where skills.Critic select skills.Amount; }
            var max = result.Concat(new[] {(long) 0}).Max();
            _caching.Add(key, max);
            return max;
        }

        public IEnumerable<Tera.Game.Skill> SkillsIdBySource(UserEntity source, Entity target, bool timed)
        {
            IEnumerable<Tera.Game.Skill> result;


            if (!SourceTargetSkill.ContainsKey(source)) { return new List<Tera.Game.Skill>(); }
            if (timed || target == null )
            {
                result = from skills in SourceTargetSkill[source].Values
                    from skill in skills
                    select SkillResult.GetSkill(source, skill.Pet, skill.SkillId, skill.HotDot, NetworkController.Instance.EntityTracker,
                        BasicTeraData.Instance.SkillDatabase, BasicTeraData.Instance.HotDotDatabase, BasicTeraData.Instance.PetSkillDatabase);

                return result.Distinct();
            }

            if (!SourceTargetSkill.ContainsKey(target)) { return new List<Tera.Game.Skill>(); }
            result = from skills in SourceTargetSkill[source][target]
                select SkillResult.GetSkill(source, skills.Pet, skills.SkillId, skills.HotDot, NetworkController.Instance.EntityTracker,
                    BasicTeraData.Instance.SkillDatabase, BasicTeraData.Instance.HotDotDatabase, BasicTeraData.Instance.PetSkillDatabase);
            return result.Distinct();
        }


        public IEnumerable<KeyValuePair<Entity, Tera.Game.Skill>> SkillsIdByTarget(Entity target)
        {
            if (!TargetSourceSkill.ContainsKey(target)) { return new List<KeyValuePair<Entity, Tera.Game.Skill>>(); }

            var result = from skills in TargetSourceSkill[target].Values
                from skill in skills
                select new KeyValuePair<Entity, Tera.Game.Skill>(skill.Source,
                    SkillResult.GetSkill(skill.Source, skill.Pet, skill.SkillId, skill.HotDot, NetworkController.Instance.EntityTracker,
                        BasicTeraData.Instance.SkillDatabase, BasicTeraData.Instance.HotDotDatabase, BasicTeraData.Instance.PetSkillDatabase));
            return result.Where(x => x.Value != null).Distinct();
        }

        public bool Type(Entity source, Entity target, int skillid, NpcInfo pet, bool timed, Database.Type type)<commit_msg>ups, forgot to push save before commit<commit_after>﻿using System.Collections.Generic;
using System.Linq;
using Data;
using Tera.Game;

namespace DamageMeter.Database.Structures
{
    public class Skills
    {
        private readonly Dictionary<string, object> _caching = new Dictionary<string, object>();

        public Skills(Dictionary<Entity, Dictionary<Entity, List<Skill>>> sourceTargetSkill, Dictionary<Entity, Dictionary<Entity, List<Skill>>> targetSourceSkill,
            Dictionary<Entity, Dictionary<Entity, Dictionary<int, List<Skill>>>> sourceTargetIdSkill, Dictionary<Entity, Dictionary<int, List<Skill>>> sourceIdSkill)
        {
            SourceTargetSkill = sourceTargetSkill;
            TargetSourceSkill = targetSourceSkill;
            SourceIdSkill = sourceIdSkill;
            SourceTargetIdSkill = sourceTargetIdSkill;
        }


        private Dictionary<Entity, Dictionary<Entity, List<Skill>>> SourceTargetSkill { get; }
        private Dictionary<Entity, Dictionary<Entity, List<Skill>>> TargetSourceSkill { get; }
        private Dictionary<Entity, Dictionary<int, List<Skill>>> SourceIdSkill { get; }
        private Dictionary<Entity, Dictionary<Entity, Dictionary<int, List<Skill>>>> SourceTargetIdSkill { get; }

        public List<Player> GetPlayers()
        {
            return SourceIdSkill.Keys.Where(x => x is UserEntity).Select(x=>NetworkController.Instance.PlayerTracker.Get(((UserEntity)x).ServerId, ((UserEntity)x).PlayerId)).ToList();
        }

        public long DamageReceived(Entity target, Entity source, bool timed)
        {
            var sourceString = source?.Id.ToString() ?? "";
            var key = "damage_received/" + target + "/" + sourceString + "/" + timed;
            if (_caching.ContainsKey(key)) { return (long) _caching[key]; }
            IEnumerable<long> result = new List<long>();

            if (TargetSourceSkill.ContainsKey(target))
            {
                if (!timed && source != null)
                {
                    if (TargetSourceSkill[target].ContainsKey(source))
                    {
                        result = from skills in TargetSourceSkill[target][source] where skills.Type == Database.Type.Damage select skills.Amount;
                    }
                }
                else { result = from skills in TargetSourceSkill[target].Values from skill in skills where skill.Type == Database.Type.Damage select skill.Amount; }
            }

            var sum = result.Sum();
            _caching.Add(key, sum);
            return sum;
        }

        public int HitsReceived(Entity target, Entity source, bool timed)
        {
            var sourceString = source?.Id.ToString() ?? "";
            var key = "hits_received/" + target + "/" + sourceString + "/" + timed;
            if (_caching.ContainsKey(key)) { return (int) _caching[key]; }

            IEnumerable<Skill> result = new List<Skill>();
            if (TargetSourceSkill.ContainsKey(target))
            {
                if (!timed && source != null)
                {
                    if (TargetSourceSkill[target].ContainsKey(source))
                    {
                        result = from skills in TargetSourceSkill[target][source] where skills.Type == Database.Type.Damage select skills;
                    }
                }
                else { result = from skills in TargetSourceSkill[target].Values from skill in skills where skill.Type == Database.Type.Damage select skill; }
            }

            var count = result.Count();
            _caching.Add(key, count);
            return count;
        }

        public long BiggestCrit(Entity source, Entity target, bool timed)
        {
            var targetString = target?.Id.ToString() ?? "";
            var key = "biggest_crit/" + source + "/" + targetString + "/" + timed;
            if (_caching.ContainsKey(key)) { return (long) _caching[key]; }

            IEnumerable<long> result;

            if (timed || target == null)
            {
                result = from skills in SourceTargetSkill[source].Values
                    from skill in skills
                    where skill.Type == Database.Type.Damage
                    where skill.Critic
                    select skill.Amount;
            }
            else { result = from skills in SourceTargetSkill[source][target] where skills.Type == Database.Type.Damage where skills.Critic select skills.Amount; }
            var max = result.Concat(new[] {(long) 0}).Max();
            _caching.Add(key, max);
            return max;
        }

        public IEnumerable<Tera.Game.Skill> SkillsIdBySource(UserEntity source, Entity target, bool timed)
        {
            IEnumerable<Tera.Game.Skill> result;


            if (!SourceTargetSkill.ContainsKey(source)) { return new List<Tera.Game.Skill>(); }
            if (timed || target == null )
            {
                result = from skills in SourceTargetSkill[source].Values
                    from skill in skills
                    select SkillResult.GetSkill(source, skill.Pet, skill.SkillId, skill.HotDot, NetworkController.Instance.EntityTracker,
                        BasicTeraData.Instance.SkillDatabase, BasicTeraData.Instance.HotDotDatabase, BasicTeraData.Instance.PetSkillDatabase);

                return result.Distinct();
            }

            if (!SourceTargetSkill[source].ContainsKey(target)) { return new List<Tera.Game.Skill>(); }
            result = from skills in SourceTargetSkill[source][target]
                select SkillResult.GetSkill(source, skills.Pet, skills.SkillId, skills.HotDot, NetworkController.Instance.EntityTracker,
                    BasicTeraData.Instance.SkillDatabase, BasicTeraData.Instance.HotDotDatabase, BasicTeraData.Instance.PetSkillDatabase);
            return result.Distinct();
        }


        public IEnumerable<KeyValuePair<Entity, Tera.Game.Skill>> SkillsIdByTarget(Entity target)
        {
            if (!TargetSourceSkill.ContainsKey(target)) { return new List<KeyValuePair<Entity, Tera.Game.Skill>>(); }

            var result = from skills in TargetSourceSkill[target].Values
                from skill in skills
                select new KeyValuePair<Entity, Tera.Game.Skill>(skill.Source,
                    SkillResult.GetSkill(skill.Source, skill.Pet, skill.SkillId, skill.HotDot, NetworkController.Instance.EntityTracker,
                        BasicTeraData.Instance.SkillDatabase, BasicTeraData.Instance.HotDotDatabase, BasicTeraData.Instance.PetSkillDatabase));
            return result.Where(x => x.Value != null).Distinct();
        }

        public bool Type(Entity source, Entity target, int skillid, NpcInfo pet, bool timed, Database.Type type)
{'fraction_non_alphanumeric': 0.10252025871682403, 'fraction_numerical': 0.0001486878299011226, 'mean_word_length': 2.2375451263537904, 'pattern_counts': {'":': 0, '<': 89, '<?xml version=': 0, '>': 95, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3098261', 'n_tokens_mistral': 3528, 'n_tokens_neox': 3376, 'n_words': 785}