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:
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
}
}