using Oxide.Core.Plugins; using Oxide.Game.Rust.Cui; using UnityEngine; using Oxide.Core; using System.Collections.Generic; using System.Linq; using System.Text; namespace Oxide.Plugins { [Info("KDNotifier", "Cengizhanbucak", "1.0.0")] public class KDNotifier : RustPlugin { private const string KD_ELEMENT_NAME = "KDNotifierElement"; private Dictionary playerData = new Dictionary(); private Dictionary playerTimers = new Dictionary(); private ConfigData configData; private class ConfigData { public string mystatsMessage { get; set; } public string top15Message { get; set; } // Add this property } protected override void LoadDefaultConfig() { configData = new ConfigData { mystatsMessage = "Merhaba {0}\ntoplam öldürme: {1}\nHS öldürme: {2}\ntoplam ölme: {3}\nKD ortalaması: {4:0.00}", top15Message = "KD ortalaması en yüksek olan ilk 10 oyuncu:\n{0}" }; SaveConfig(); } protected override void LoadConfig() { base.LoadConfig(); configData = Config.ReadObject(); } protected override void SaveConfig() => Config.WriteObject(configData); private void Loaded() { playerData = Interface.Oxide.DataFileSystem.ReadObject>("KDNotifier") ?? new Dictionary(); } private void SaveData() { Interface.Oxide.DataFileSystem.WriteObject("KDNotifier", playerData); } private void RemovePreviousNotification(BasePlayer player) { CuiHelper.DestroyUi(player, KD_ELEMENT_NAME); } public class PlayerData { public int Kills = 0; public int Deaths = 0; public int Headshots = 0; // Yeni özellik: Headshot sayısı public string PlayerName { get; set; } // Oyuncu ismi public float KD => Deaths == 0 ? Kills : (float)Kills / Deaths; } private void OnPlayerDeath(BasePlayer player, HitInfo info) { if (info?.InitiatorPlayer == null) return; BasePlayer attacker = info.InitiatorPlayer; if (attacker == player) return; // Ignore suicides if (!playerData.ContainsKey(attacker.userID)) playerData[attacker.userID] = new PlayerData(); playerData[attacker.userID].Kills++; playerData[attacker.userID].PlayerName = attacker.displayName; // Oyuncu ismini kaydet // Headshot kontrolü if (info.isHeadshot) { playerData[attacker.userID].Headshots++; } SaveData(); DisplayKDForPlayer(attacker, true); } private void OnEntityDeath(BaseEntity entity, HitInfo info) { BasePlayer player = entity as BasePlayer; if (player == null) return; if (!playerData.ContainsKey(player.userID)) playerData[player.userID] = new PlayerData(); playerData[player.userID].Deaths++; playerData[player.userID].PlayerName = player.displayName; // Oyuncu ismini kaydet // Headshot kontrolü if (info != null && info.isHeadshot) { playerData[player.userID].Headshots++; } SaveData(); DisplayKDForPlayer(player, false); } private void DisplayKDForPlayer(BasePlayer player, bool isKill) { if (!playerData.ContainsKey(player.userID)) return; var kd = playerData[player.userID].KD; var headshots = playerData[player.userID].Headshots; // Headshot sayısı RemovePreviousNotification(player); // Remove any existing notification var element = new CuiElementContainer(); var panel = element.Add(new CuiPanel { Image = { Color = isKill ? "0 1 0 0.16" : "1 0 0 0.16" }, // Green for kill, Red for death RectTransform = { AnchorMin = "0.6319 0.025", AnchorMax = "0.700 0.108" }, CursorEnabled = false }, "Overlay", KD_ELEMENT_NAME); element.Add(new CuiLabel { Text = { Text = $"KD: {kd:0.##} - HS: {headshots}", FontSize = 14, Align = TextAnchor.MiddleCenter }, // Headshot sayısını ekleyin RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" } }, panel); CuiHelper.AddUi(player, element); // If there's an existing timer for this player, destroy it if (playerTimers.ContainsKey(player.userID) && playerTimers[player.userID] != null) { playerTimers[player.userID].Destroy(); playerTimers.Remove(player.userID); // Remove the timer reference from the dictionary } // Start a new timer to remove the notification after 5 seconds and store its reference playerTimers[player.userID] = timer.Once(5f, () => RemovePreviousNotification(player)); } // KDNotifier eklentisinde: [HookMethod("GetPlayerKDData")] public PlayerData GetPlayerKDData(ulong userId) { if (playerData.ContainsKey(userId)) { return playerData[userId]; } return null; } [ChatCommand("mystats")] private void MyStatsCommand(BasePlayer player, string command, string[] args) { if (player == null) return; PlayerData data; if (!playerData.TryGetValue(player.userID, out data)) { SendReply(player, "Verileriniz bulunamadı."); return; } string message = string.Format(configData.mystatsMessage, player.displayName, data.Kills, data.Headshots, data.Deaths, data.KD); SendReply(player, message); } [ChatCommand("top15")] private void Top15Command(BasePlayer player, string command, string[] args) { if (player == null) return; var topPlayers = playerData.Values.OrderByDescending(p => p.KD).ThenByDescending(p => p.Headshots).Take(10).ToList(); var message = new StringBuilder(); for (int i = 0; i < topPlayers.Count; i++) { message.AppendLine($"{i + 1}. {topPlayers[i].PlayerName} - KD: {topPlayers[i].KD:0.00}, Headshots: {topPlayers[i].Headshots}"); } SendReply(player, string.Format(configData.top15Message, message.ToString())); } } }