using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Oxide.Core; using Oxide.Core.Plugins; using Newtonsoft.Json; // ____ _ _ _ // / ___|(_) __ _(_) | ___ // \___ \| |/ _` | | |/ _ \ // ___) | | (_| | | | (_) | // |____/|_|\__, |_|_|\___/ // |___/ // ☽✧✵✧✵✧✵✧✵✧✵✧✵✧☾ // ✦ RUST PLUGINS ✦ // ✦ Sigilo.dev ✦ // ☽✧✵✧✵✧✵✧✵✧✵✧✵✧☾ namespace Oxide.Plugins { [Info("KDR", "Sigilo", "1.0.1")] [Description("Shows kills, deaths, KDR and a top 10 leaderboard")] class KDR : RustPlugin { private const string PERMISSION_NAME = "kdr.use"; private ConcurrentDictionary playerStats = new ConcurrentDictionary(); private ConcurrentDictionary playerKDR = new ConcurrentDictionary(); class PlayerKDR { public string UserID { get; set; } public string Name { get; set; } public float KDR { get; set; } } void Init() { permission.RegisterPermission(PERMISSION_NAME, this); cmd.AddChatCommand("kdr", this, "CmdKDR"); cmd.AddChatCommand("kdrtop", this, "CmdKDRTop"); } void Loaded() { var data = Interface.Oxide.DataFileSystem.ReadObject>("KDRData"); foreach (var entry in data) { playerStats[entry.Key] = entry.Value; } try { playerKDR = new ConcurrentDictionary(Interface.Oxide.DataFileSystem.ReadObject>("KDR").ToDictionary(entry => entry.Key, entry => entry.Value)); } catch (JsonReaderException) { Puts("Error reading KDR data. The data might be in an incorrect format."); playerKDR = new ConcurrentDictionary(); } } void Unload() { Interface.Oxide.DataFileSystem.WriteObject("KDRData", playerStats.ToDictionary(entry => entry.Key, entry => entry.Value)); Interface.Oxide.DataFileSystem.WriteObject("KDR", playerKDR.ToDictionary(entry => entry.Key, entry => entry.Value)); } void OnPlayerDeath(BasePlayer player, HitInfo info) { if (info?.InitiatorPlayer != null && player != null && player.userID != 0) { if (info.InitiatorPlayer.userID != player.userID) { OnPlayerKill(info.InitiatorPlayer, player); } } } void OnPlayerKill(BasePlayer killer, BasePlayer victim) { string killerId = killer.UserIDString; string victimId = victim.UserIDString; if (!IsValidSteamID(victim.userID)) { return; } playerStats.AddOrUpdate(killerId, (1, 0), (key, oldValue) => (oldValue.Kills + 1, oldValue.Deaths)); playerStats.AddOrUpdate(victimId, (0, 1), (key, oldValue) => (oldValue.Kills, oldValue.Deaths + 1)); Task.Run(() => UpdateKDR(killerId, victimId)); } async Task UpdateKDR(string killerId, string victimId) { float killerKDR = CalculateKDR(killerId); float victimKDR = CalculateKDR(victimId); playerKDR[killerId] = new PlayerKDR { UserID = killerId, Name = covalence.Players.FindPlayerById(killerId)?.Name ?? "Unknown", KDR = killerKDR }; playerKDR[victimId] = new PlayerKDR { UserID = victimId, Name = covalence.Players.FindPlayerById(victimId)?.Name ?? "Unknown", KDR = victimKDR }; } float CalculateKDR(string playerId) { var stats = playerStats.GetOrAdd(playerId, (0, 0)); return stats.Deaths != 0 ? (float)stats.Kills / stats.Deaths : stats.Kills; } [ChatCommand("kdr")] void CmdKDR(BasePlayer player, string command, string[] args) { string playerId = player.UserIDString; if (!permission.UserHasPermission(playerId, PERMISSION_NAME)) { SendReply(player, "You do not have permission to use this command."); return; } var stats = playerStats.GetOrAdd(playerId, (0, 0)); float kdr = playerKDR.ContainsKey(playerId) ? playerKDR[playerId].KDR : CalculateKDR(playerId); SendReply(player, $"Your kills: {stats.Kills}, deaths: {stats.Deaths}, KDR: {kdr.ToString("0.0")}."); } [ChatCommand("kdrtop")] void CmdKDRTop(BasePlayer player, string command, string[] args) { string playerId = player.UserIDString; if (!permission.UserHasPermission(playerId, PERMISSION_NAME)) { SendReply(player, "You do not have permission to use this command."); return; } var topKDRs = playerKDR.Values.OrderByDescending(x => x.KDR).Take(10); string message = "Top KDRs:\n"; foreach (var kdr in topKDRs) { string kdrString = kdr.KDR.ToString("0.0").PadRight(5); message += $"{kdrString}| {kdr.Name}\n"; } SendReply(player, message); } void SendReply(BasePlayer player, string message) { player.ChatMessage(message); } bool IsValidSteamID(ulong userID) { string userIDString = userID.ToString(); return userIDString.StartsWith("7656") && userIDString.Length == 17; } } }