Dictionary given key was not presentNot An Issue
Im using the SimplePvpStats plugin as base to make a better version out of it.

Im Trying to add the Pvpinfo to the Dictionary but i always get that error and i cant figure it out. Maybe someone else got an idea.

(Ignore the info settings at server start didnt work)


Error:
Failed to call hook 'OnPlayerDie' on plugin 'SimplePVPStats v1.0.0' (KeyNotFoundException: The given key was not present in the dictionary.)
  at System.Collections.Generic.Dictionary`2[TKey,TValue].get_Item (TKey key) [0x0001e] in <e1a80661d61443feb3dbdaac88eeb776>:0
  at Oxide.Plugins.SimplePVPStats.OnPlayerDie (BasePlayer victim, HitInfo info) [0x000e1] in <73b296f7bea044c7be645ee4016bf6a7>:0
  at Oxide.Plugins.SimplePVPStats.DirectCallHook (System.String name, System.Object& ret, System.Object[] args) [0x0020d] in <73b296f7bea044c7be645ee4016bf6a7>:0
  at Oxide.Plugins.CSharpPlugin.InvokeMethod (Oxide.Core.Plugins.HookMethod method, System.Object[] args) [0x00079] in <9affce1cd15c4ec183941adef8db1722>:0
  at Oxide.Core.Plugins.CSPlugin.OnCallHook (System.String name, System.Object[] args) [0x000d8] in <4452f821def6406d834e4149849fe7ea>:0
  at Oxide.Core.Plugins.Plugin.CallHook (System.String hook, System.Object[] args) [0x00060] in <4452f821def6406d834e4149849fe7ea>:0​



using Oxide.Core;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using System.Linq;
using Oxide.Core.Libraries.Covalence;

namespace Oxide.Plugins
{
    [Info("Simple PvP Stats", "", "1.0.0")]
    [Description("Simple Pvp Statistics")]
    class SimplePVPStats : RustPlugin
    {
        #region Declaration

        private Dictionary<ulong, SimplePVPStatsData> cachedPlayerStats = new Dictionary<ulong, SimplePVPStatsData>();
        static SimplePVPStats ins;

        #endregion

        #region Hooks

        private void OnServerInitialized()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["PlayerStatisticsMSGPVP"] = "<color=#ffc300>Your PvP Statistics</color> : <color=#ffc300>{0}</color> Kills, <color=#ffc300>{1}</color> Deaths, <color=#ffc300>{2}</color> K/D Ratio",
                ["PlayerStatisticsMSGPVE"] = "<color=#ffc300>Your PvE Statistics</color> : <color=#ffc300>{0}</color> Kills, <color=#ffc300>{1}</color> Deaths, <color=#ffc300>{2}</color> K/D Ratio",
                ["ConsoleWipeMSG"] = "{0} Players Pvp Statistics were wiped!",
                ["ConsoleResetMSG"] = "{0} PvP Statistics has been reset",
                ["ConsoleNotFoundMSG"] = "{0} Not Found!",
            }, this);

            ins = this;
            BasePlayer.activePlayerList.ForEach(player => 
            {
                if (player != null) OnPlayerInit(player);
                var i = new PvPInfo();
                i.Distance = 0;
                i.KilledBy = "Test";
                i.Weapon = "Fuck yoU";
                i.Headshot = true;
                cachedPlayerStats[player.userID].pvpInfo.Add(0, i);
            });
        }

        private void OnPlayerInit(BasePlayer player) => SimplePVPStatsData.TryLoad(player.userID);

        private void OnPlayerDie(BasePlayer victim, HitInfo info)
        {
            BasePlayer killer = info?.Initiator as BasePlayer;

            if (killer == null || killer == victim) return;
            if (victim.IsNpc) return;

            if (cachedPlayerStats.ContainsKey(victim.userID) && killer.IsNpc) cachedPlayerStats[victim.userID].NPCDeaths++;
            if (cachedPlayerStats.ContainsKey(killer.userID)) cachedPlayerStats[killer.userID].Kills++;
            if (cachedPlayerStats.ContainsKey(victim.userID)) cachedPlayerStats[victim.userID].Deaths++;

            int count = cachedPlayerStats[killer.userID].pvpInfo.Count + 1;
            var i = new PvPInfo();
            i.Distance = info.ProjectileDistance;
            i.KilledBy = killer.displayName.ToString();
            i.Weapon = info.Weapon._name;
            i.Headshot = info.isHeadshot;
            cachedPlayerStats[killer.userID].pvpInfo.Add(count, i);
            return;
        }

        private void OnEntityDeath(BaseCombatEntity entity, HitInfo info)
        {
            BasePlayer player = info?.Initiator as BasePlayer;

            if (cachedPlayerStats.ContainsKey(player.userID)) cachedPlayerStats[player.userID].NPCKills++;
            return;
        }


        private void OnServerShutDown() => Unload();

        private void Unload()
        {
            foreach (var data in cachedPlayerStats) data.Value.Save(data.Key);
        }

        #endregion

        #region Commands       

        [ConsoleCommand("stats.wipe")]
        private void WipeStatsCmd(ConsoleSystem.Arg arg)
        {
            if (!arg.IsRcon) return;

            GetAllPlayers().ForEach(ID => SimplePVPStatsData.Reset(ID));
            PrintWarning(string.Format(msg("ConsoleWipeMSG"), new object[] { GetAllPlayers().Count }));
        }

        [ConsoleCommand("stats.reset")]
        private void ResetStatsCmd(ConsoleSystem.Arg arg)
        {
            if (!arg.IsRcon) return;
            if (!arg.HasArgs()) return;

            if (arg.Args.Count() != 1)
            {
                PrintWarning($"Usage : stats.reset <SteamID64>");
                return;
            }

            string ID = arg.Args[0];

            if (!ID.IsSteamId())
            {
                PrintWarning(string.Format(msg("ConsoleNotFoundMSG"), new object[] { ID }));
                return;
            }

            string Name = GetPlayer(ulong.Parse(ID));

            PrintWarning(string.Format(msg("ConsoleResetMSG"), new object[] { Name }));
        }

        [ChatCommand("stats")]
        private void cmdShowStatistics(BasePlayer player, string command, string[] args)
        {
            PlayerMsg(player, string.Format(msg("PlayerStatisticsMSGPVP", player.userID), new object[] { cachedPlayerStats[player.userID].Kills, cachedPlayerStats[player.userID].Deaths, cachedPlayerStats[player.userID].PvPKDR }));
            PlayerMsg(player, string.Format(msg("PlayerStatisticsMSGPVE", player.userID), new object[] { cachedPlayerStats[player.userID].NPCKills, cachedPlayerStats[player.userID].NPCDeaths, cachedPlayerStats[player.userID].PveKDR }));
        }

        #endregion

        #region Methods

        public List<ulong> GetAllPlayers()
        {
            List<ulong> PlayersID = new List<ulong>();
            covalence.Players.All.ToList().ForEach(IPlayer => PlayersID.Add(ulong.Parse(IPlayer.Id)));
            return PlayersID;
        }

        public string GetPlayer(ulong id)
        {
            IPlayer player = covalence.Players.FindPlayerById(id.ToString());
            if (player == null) return string.Empty;
            return player.Name;
        }

        public void PlayerMsg(BasePlayer player, string msg) => SendReply(player, msg);

        #endregion

        #region Classes


        public class PvPInfo
        {
            public string KilledBy = "";

            public string Weapon = "";
            public float Distance = 0f;
            public bool Headshot = false;
        }

        public class SimplePVPStatsData
        {

            public int NPCDeaths = 0;
            public int NPCKills = 0;
            public float PveKDR => NPCDeaths == 0 ? NPCKills : (float)Math.Round(((float)NPCKills) / NPCDeaths, 4);

            public int Kills = 0;
            public int Deaths = 0;
            public float PvPKDR => Deaths == 0 ? Kills : (float)Math.Round(((float)Kills) / Deaths, 4);


            public Dictionary<int, PvPInfo> pvpInfo = new Dictionary<int, PvPInfo>();

            internal static void TryLoad(ulong id)
            {
                if (ins.cachedPlayerStats.ContainsKey(id)) return;

                SimplePVPStatsData data = Interface.Oxide.DataFileSystem.ReadObject<SimplePVPStatsData>($"SimplePvPStats/{id}");

                if (data == null) data = new SimplePVPStatsData();

                ins.cachedPlayerStats.Add(id, data);
            }

            internal static void Reset(ulong id)
            {
                SimplePVPStatsData data = Interface.Oxide.DataFileSystem.ReadObject<SimplePVPStatsData>($"SimplePvPStats/{id}");

                if (data == null) return;

                data = new SimplePVPStatsData();
                data.Save(id);
            }

            internal void Save(ulong id) => Interface.Oxide.DataFileSystem.WriteObject(($"SimplePvPStats/{id}"), this, true);
        }

        #endregion

        #region Localization

        public string msg(string key, ulong playerId = 0U) => lang.GetMessage(key, this, playerId != 0U ? playerId.ToString() : null);

        #endregion
    }
}



This error means you don't have this key in the dictionary. 
Int count = ...[killer.userId], no check here if dictionary contains it.
I changed it a litte but still getting errors. I dont get it with dicts here..

if the count !>= 0 then i tried to add a new pvpinfo with 0 and the info but i get this error then and i have no clue how to fix, maybe you can change the code to get it working. 

Thanks for help

Failed to call hook 'OnPlayerDie' on plugin 'SimplePVPStats v1.0.0' (NullReferenceException: Object reference not set to an instance of an object)
  at Oxide.Plugins.SimplePVPStats.OnPlayerDie (BasePlayer victim, HitInfo info) [0x00157] in <34c8b42e9db84657ae1ea3fd6307fd9e>:0
  at Oxide.Plugins.SimplePVPStats.DirectCallHook (System.String name, System.Object& ret, System.Object[] args) [0x0020d] in <34c8b42e9db84657ae1ea3fd6307fd9e>:0
  at Oxide.Plugins.CSharpPlugin.InvokeMethod (Oxide.Core.Plugins.HookMethod method, System.Object[] args) [0x00079] in <9affce1cd15c4ec183941adef8db1722>:0
  at Oxide.Core.Plugins.CSPlugin.OnCallHook (System.String name, System.Object[] args) [0x000d8] in <4452f821def6406d834e4149849fe7ea>:0
  at Oxide.Core.Plugins.Plugin.CallHook (System.String hook, System.Object[] args) [0x00060] in <4452f821def6406d834e4149849fe7ea>:0​


  private void OnPlayerDie(BasePlayer victim, HitInfo info)
        {
            BasePlayer killer = info?.Initiator as BasePlayer;

            if (killer == null || killer == victim)
                return;
            if (victim.IsNpc)
                return;

            if (cachedPlayerStats.ContainsKey(victim.userID) && killer.IsNpc)
                cachedPlayerStats[victim.userID].NPCDeaths++;

            if (cachedPlayerStats.ContainsKey(killer.userID))
                cachedPlayerStats[killer.userID].Kills++;

            if (cachedPlayerStats.ContainsKey(victim.userID))
                cachedPlayerStats[victim.userID].Deaths++;

            if (cachedPlayerStats.ContainsKey(victim.userID) && cachedPlayerStats[victim.userID].pvpInfo.Count >= 0)
            {

                int count = cachedPlayerStats[victim.userID].pvpInfo.Count;
                var i = new PvPInfo();
                i.Distance = info.ProjectileDistance;
                i.KilledBy = killer.displayName.ToString();
                i.Weapon = info.Weapon._name;
                i.Headshot = info.isHeadshot;
                cachedPlayerStats[victim.userID].pvpInfo.Add(count + 1, i);
                Puts("[PvPInfo]" + string.Format("Count: {0}\nInfo: {1}", count, i.ToString()));
            }
            else
            {
                var i = new PvPInfo();
                cachedPlayerStats[victim.userID].pvpInfo[0] = i;
                Puts("[PvPInfo] New info has been set");
            }
            return;
        }​
  1. Don't check with ContainsKey 20 times, you only need to check and handle it once; if it doesn't exist, don't continue else create a new entry or whatever. You'll encounter KeyNotFoundException with the above code you posted eventually, as you aren't properly checking before usage still.
  2. You're assuming ththat there is HitInfo, which is likely where the NullReferenceException is coming from; always null check that sort of thing
In response to Wulf ():
Don't check with ContainsKey 20 times, you only need to check and handle it once; if it doesn't exi...
Give me an example how to do it properly i dont know it fr.
if (..)
{
// Code 1
// Code 2
// Code n
}
Locked automatically