C#:
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<ulong, PlayerData> playerData = new Dictionary<ulong, PlayerData>();
private Dictionary<ulong, Timer> playerTimers = new Dictionary<ulong, Timer>();
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<ConfigData>();
}
protected override void SaveConfig() => Config.WriteObject(configData);
private void Loaded()
{
playerData = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<ulong, PlayerData>>("KDNotifier") ?? new Dictionary<ulong, PlayerData>();
}
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()));
}
}
}