KeyNotFoundException with my pluginSolved
void OnEntityDeath(BaseCombatEntity entity, HitInfo info)
        {
            BasePlayer killer = info?.Initiator as BasePlayer;

            if (entity == null | info == null) return;

            if (killer == null || killer == entity) return;

         


                if (entity.ShortPrefabName == "heavyscientist")
            {
                if ((bool)Config["Count Heavy Scientists"] == true)
                    if (Cachedplayerstats.ContainsKey(killer.userID)) Cachedplayerstats[killer.userID].heavyKills++;
            }
            if (entity.ShortPrefabName == "scientist")
            {
                if ((bool)Config["Count Scientists"] == true) 
                    if (Cachedplayerstats.ContainsKey(killer.userID)) Cachedplayerstats[killer.userID].scientistkills++;
            }
                              
            if (entity.ShortPrefabName == "murderer")
            {
                if((bool)Config["Count Murderers"] == true)
                    if (Cachedplayerstats.ContainsKey(killer.userID)) Cachedplayerstats[killer.userID].murdererkills++;
            }
            if (entity.ShortPrefabName == "scarecrow")
            {
                if((bool)Config["Count Scarecrow"] == true)
                    if (Cachedplayerstats.ContainsKey(killer.userID)) Cachedplayerstats[killer.userID].scarecrowkills++;
            }


            
            
            
            foreach (var data in Cachedplayerstats) data.Value.Save(data.Key);
            CheckPlayerKills(killer);
            return;




public void CheckPlayerKills(BasePlayer player) 
        {
            if (Cachedplayerstats[player.userID].heavyKills == (int)Config["First Heavy Threshold"]) 
            {
                PrintToConsole("oxide.usergroup add",player.userID,(string)Config["First Heavy Threshold Oxide Group"]);
            }
        }

I made this function that is supposed to check if the player has reached a kill threshold, and if so, add them to an oxide group. When the function is called I get errors in the console. Any idea why?

What errors do you get?
Failed to call hook 'OnEntityDeath' on plugin 'NPCKillCounter 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 <437ba245d8404784b9fbab9b439ac908>:0                                  
  at Oxide.Plugins.NPCKillCounter.CheckPlayerKills (BasePlayer player) [0x00000] in <c9e4ed2d6ed04b6f8db2fd64cf5b002a>:0
  at Oxide.Plugins.NPCKillCounter.OnEntityDeath (BaseCombatEntity entity, HitInfo info) [0x0020e] in <c9e4ed2d6ed04b6f8db2fd64cf5b002a>:0
  at Oxide.Plugins.NPCKillCounter.DirectCallHook (System.String name, System.Object& ret, System.Object[] args) [0x00177] in <c9e4ed2d6ed04b6f8db2fd64cf5b002a>:0
  at Oxide.Plugins.CSharpPlugin.InvokeMethod (Oxide.Core.Plugins.HookMethod method, System.Object[] args) [0x00079] in <d09a1f46ca2f4432811bcfe45ad13c7b>:0
  at Oxide.Core.Plugins.CSPlugin.OnCallHook (System.String name, System.Object[] args) [0x000d8] in <cf88a28c7fb44d36890d85a78331cc9d>:0
  at Oxide.Core.Plugins.Plugin.CallHook (System.String hook, System.Object[] args) [0x00060] in <cf88a28c7fb44d36890d85a78331cc9d>:0
The error is from:
if (Cachedplayerstats[player.userID].heavyKills​
It isn't checked if it contains the key before use. You could probably condense the checks there too.
5e13a8d5b2bc5.jpg Wulf
The error is from:
if (Cachedplayerstats[player.userID].heavyKills​
It isn't checked if it contains the key before use. You could probably condense the checks there too.
 public void CheckPlayerKills(BasePlayer player) 
        {


            if (Cachedplayerstats.ContainsKey(player.userID)) if (Cachedplayerstats[player.userID].heavyKills == (int)Config["First Heavy Threshold"])
            {
                PrintToConsole("oxide.usergroup add",player.userID,(string)Config["First Heavy Threshold Oxide Group"]);
            }
        }​

is this how i would fix it?

That would be one way, yes.

PrintToConsole will not run commands by the way, and you should use methods, not commands, to add players to groups.
5e13a8d5b2bc5.jpg Wulf
That would be one way, yes.

PrintToConsole will not run commands by the way, and you should use methods, not commands, to add players to groups.

that way still gives the same errors, any idea why?

5ee8d1e1c84dc.png Kingfoo55

that way still gives the same errors, any idea why?

I find that unlikely. Could you show all of your code please?

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

namespace Oxide.Plugins
{
    [Info("NPC Kill Counter", "Kingfoo55", "1.0.0")]
    [Description("Counts NPC Kills and adds players to an oxide group once a threshold is reached.")]
    public class NPCKillCounter : RustPlugin
    {
        #region Declaration
        static NPCKillCounter ins;
        static Dictionary<ulong, PVEStatsData> Cachedplayerstats = new Dictionary<ulong, PVEStatsData>();

        public bool UseScientists;
        public bool UseHeavy;
        public bool UseMurderer;
        public bool UseScarecrow;
        
        #endregion

        #region Config & Localisation

        protected override void LoadDefaultConfig()
        {
            Config["Count Scientists"] = UseScientists = true;
            Config["Count Heavy Scientists"] = UseHeavy = true;
            Config["Count Murderers"] = UseMurderer = true;
            Config["Count Scarecrow"] = UseScarecrow = true;
            Config["first scientist threshhold"] = 50;
            Config["first heavy scientist threshhold"] = 50;
            Config["first murderer threshhold"] = 50;
            Config["first scarecrow threshhold"] = 50;
            Config["second scientist threshhold"] = 100;
            Config["second heavy scientist threshhold"] = 100;
            Config["second murderer threshhold"] = 100;
            Config["second scarecrow threshhold"] = 100;
            Config["first scientist threshold oxide group"] = "group1scientist";
            Config["first heavy scientist threshold oxide group"] = "group1heavy";
            Config["first murderer threshold oxide group"] = "group1murderer";
            Config["first scarecrow threshold oxide group"] = "group1scarecrow";
            Config["second scientist threshold oxide group"] = "group2scientist";
            Config["second heavy scientist threshold oxide group"] = "group2heavy";
            Config["second murderer threshold oxide group"] = "group2murderer";
            Config["second scarecrow threshold oxide group"] = "group2scarecrow";

        }

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["StatsMessage"] = "<color=#55aaff>Your PVE Statistics</color> : <color=#55aaff>{0}</color> Scientist Kills, <color=#55aaff>{1}</color> Heavy Scientist Kills, <color=#55aaff>{2}</color> Murderer Kills, <color=#55aaff>{3}</color> Scarecrow Kills",
                ["ResetStats"] = "{0} Players PVE Statistics were Reset!",
                ["ClearStats"] = "{0} PVE Statistics have been cleared",
                ["NotFound"] = "{0} Not Found!",
            }, this);
        }





        #endregion
        
        #region Hooks

        private void OnServerInitialized()
        {
            ins = this;
            foreach (BasePlayer player in BasePlayer.activePlayerList) OnPlayerInit(player);
        }

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

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

            if (entity == null | info == null) return;

            if (killer == null || killer == entity) return;

         


                if (entity.ShortPrefabName == "heavyscientist")
            {
                if ((bool)Config["Count Heavy Scientists"] == true)
                    if (Cachedplayerstats.ContainsKey(killer.userID)) Cachedplayerstats[killer.userID].heavyKills++;
            }
            if (entity.ShortPrefabName == "scientist")
            { 
                if ((bool)Config["Count Scientists"] == true) 
                    if (Cachedplayerstats.ContainsKey(killer.userID)) Cachedplayerstats[killer.userID].scientistkills++;
            }
                              
            if (entity.ShortPrefabName == "murderer")
            {
                if((bool)Config["Count Murderers"] == true)
                    if (Cachedplayerstats.ContainsKey(killer.userID)) Cachedplayerstats[killer.userID].murdererkills++;
            }
            if (entity.ShortPrefabName == "scarecrow")
            {
                if((bool)Config["Count Scarecrow"] == true)
                    if (Cachedplayerstats.ContainsKey(killer.userID)) Cachedplayerstats[killer.userID].scarecrowkills++;
            }


            
            
            
            foreach (var data in Cachedplayerstats) data.Value.Save(data.Key);
            CheckPlayerKills(killer);
            return;
            

        }
        private void OnServerShutDown() => Unload();

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

        #region Commands

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

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

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

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

            string ID = arg.Args[0];

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


            

            ulong id = Convert.ToUInt64(ID);
            


            PrintWarning(string.Format(msg("ClearStats"), new object[] { id }));
            PVEStatsData.Reset(id);
        }

        [ChatCommand("pvestats")]
        private void cmdShowStatistics(BasePlayer player, string command, string[] args)
        {
            
            if (!Cachedplayerstats.ContainsKey(player.userID)) PVEStatsData.TryLoad(player.userID);
            PlayerMsg(player, string.Format(msg("StatsMessage", player.userID), new object[] { Cachedplayerstats[player.userID].scientistkills, Cachedplayerstats[player.userID].heavyKills, Cachedplayerstats[player.userID].murdererkills, Cachedplayerstats[player.userID].scarecrowkills }));
        }

        #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);

        public void CheckPlayerKills(BasePlayer player) 
        {


            if (Cachedplayerstats.ContainsKey(player.userID)) if (Cachedplayerstats[player.userID].heavyKills == (int)Config["First Heavy Threshold"])
            {
                PrintToConsole("oxide.usergroup add",player.userID,(string)Config["First Heavy Threshold Oxide Group"]);
            }
        }


        #endregion

        #region Data Class

        private class PVEStatsData
        {
            public int heavyKills = 0;
            public int scientistkills = 0;
            public int murdererkills = 0;
            public int scarecrowkills = 0;
            
            

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

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

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

                Cachedplayerstats.Add(id, data);
            }

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

                if (data == null) return;

                data = new PVEStatsData();
                data.Save(id);
                Cachedplayerstats[id].heavyKills = 0;
                Cachedplayerstats[id].scarecrowkills = 0;
                Cachedplayerstats[id].scientistkills = 0;
                Cachedplayerstats[id].murdererkills = 0;

            }

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


        }




        #endregion

        #region Localization

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

        #endregion








    }
}
And what is the current error?
            PlayerMsg(player, string.Format(msg("StatsMessage", player.userID), new object[] { Cachedplayerstats[player.userID].scientistkills, Cachedplayerstats[player.userID].heavyKills, Cachedplayerstats[player.userID].murdererkills, Cachedplayerstats[player.userID].scarecrowkills }));
That would be your issue most likely, as it falls outside of your if check due to lack of curly braces.
5e13a8d5b2bc5.jpg Wulf
And what is the current error?
            PlayerMsg(player, string.Format(msg("StatsMessage", player.userID), new object[] { Cachedplayerstats[player.userID].scientistkills, Cachedplayerstats[player.userID].heavyKills, Cachedplayerstats[player.userID].murdererkills, Cachedplayerstats[player.userID].scarecrowkills }));
That would be your issue most likely, as it falls outside of your if check due to lack of curly braces.

How can i fix it?

5ee8d1e1c84dc.png Kingfoo55

How can i fix it?

Use curly braces and include it in the if check.
if (!Cachedplayerstats.ContainsKey(player.userID)) PVEStatsData.TryLoad(player.userID);
            {
                PlayerMsg(player, string.Format(msg("StatsMessage", player.userID), new object[] { Cachedplayerstats[player.userID].scientistkills, Cachedplayerstats[player.userID].heavyKills, Cachedplayerstats[player.userID].murdererkills, Cachedplayerstats[player.userID].scarecrowkills }));
            }

I did this and it still gives me errors.

Because you still haven't enclosed it, you just added curly braces outside of the if check.
5e13a8d5b2bc5.jpg Wulf
Because you still haven't enclosed it, you just added curly braces outside of the if check.

i don't understand where i am supposed to put the brackets.

Locked automatically