using System; using System.Collections.Generic; using System.Linq; using Oxide.Core; using Oxide.Core.Plugins; using Newtonsoft.Json; // ____ _ _ _ // / ___|(_) __ _(_) | ___ // \___ \| |/ _` | | |/ _ \ // ___) | | (_| | | | (_) | // |____/|_|\__, |_|_|\___/ // |___/ // ☽✧✵✧✵✧✵✧✵✧✵✧✵✧☾ // ✦ RUST PLUGINS ✦ // ✦ Discord:sigil0 ✦ // ☽✧✵✧✵✧✵✧✵✧✵✧✵✧☾ namespace Oxide.Plugins { [Info("KillStreak", "Sigilo", "1.0.3")] [Description("Adds killstreak messages, rewards and a ranking system")] class KillStreak : RustPlugin { private const string PERMISSION_NAME = "killstreak.use"; private SortedDictionary playerKillStreak = new SortedDictionary(); private SortedDictionary playerBestKillStreak = new SortedDictionary(); private SortedDictionary> serverBestKillStreak = new SortedDictionary>(); private int killsToRestoreHealth; public const int CurrentVersion = 1; private Configuration config; public class RewardItem { public string Item { get; set; } public int Amount { get; set; } public ulong Skin { get; set; } } public class Reward { public List Items { get; set; } public string Message { get; set; } public bool BroadcastToServer { get; set; } } private SortedDictionary rewardCommands = new SortedDictionary(); public class Configuration { public SortedDictionary RewardCommands { get; set; } public int KillsToRestoreHealth { get; set; } public int Version { get; set; } public bool CountNpcKills { get; set; } public static Configuration Read(string fileName, RustPlugin plugin) { if (!plugin.Config.Exists(fileName)) { var config = new Configuration { RewardCommands = new SortedDictionary(), KillsToRestoreHealth = 5, Version = CurrentVersion, CountNpcKills = false }; plugin.Config.WriteObject(config, true); return config; } return plugin.Config.ReadObject(fileName); } } private bool UpdateConfiguration(Configuration config) { if (config.Version < CurrentVersion) { config.Version = CurrentVersion; config.RewardCommands = new SortedDictionary(); config.KillsToRestoreHealth = 5; config.CountNpcKills = false; Config.WriteObject(config, true); return true; } return false; } protected override void LoadDefaultConfig() { var defaultConfig = new Configuration { RewardCommands = new SortedDictionary { { 2, new Reward { Items = new List(), Message = "Double Kill!", BroadcastToServer = false } }, { 3, new Reward { Items = new List(), Message = "Triple Kill!", BroadcastToServer = false } }, { 5, new Reward { Items = new List(), Message = "Pentakill!", BroadcastToServer = true } }, { 10, new Reward { Items = new List(), Message = "Decimation!", BroadcastToServer = true } }, { 15, new Reward { Items = new List(), Message = "Deadly!", BroadcastToServer = true } }, { 20, new Reward { Items = new List(), Message = "Monsterkill!", BroadcastToServer = true } }, { 30, new Reward { Items = new List(), Message = "Megakill!", BroadcastToServer = true } }, { 40, new Reward { Items = new List(), Message = "Massacre!", BroadcastToServer = true } }, { 50, new Reward { Items = new List(), Message = "Unstoppable!", BroadcastToServer = true } }, { 60, new Reward { Items = new List(), Message = "Ultrakill!", BroadcastToServer = true } }, { 70, new Reward { Items = new List(), Message = "Annihilation!", BroadcastToServer = true } }, { 80, new Reward { Items = new List(), Message = "Epic!", BroadcastToServer = true } }, { 90, new Reward { Items = new List(), Message = "Godlike!", BroadcastToServer = true } }, { 100, new Reward { Items = new List(), Message = "LEGEND!!!!!", BroadcastToServer = true } } }, KillsToRestoreHealth = 5, Version = CurrentVersion, CountNpcKills = false }; Config.WriteObject(defaultConfig, true); } void Init() { permission.RegisterPermission(PERMISSION_NAME, this); cmd.AddChatCommand("ks", this, "CmdKillStreak"); cmd.AddChatCommand("kstop", this, "CmdKillStreakTop"); } void Loaded() { config = Configuration.Read("oxide/config/KillStreak.json", this); if (config.Version < CurrentVersion) { UpdateConfiguration(config); config = Configuration.Read("oxide/config/KillStreak.json", this); } rewardCommands = config.RewardCommands; killsToRestoreHealth = config.KillsToRestoreHealth; playerBestKillStreak = Interface.Oxide.DataFileSystem.ReadObject>("KillStreakBest"); serverBestKillStreak = Interface.Oxide.DataFileSystem.ReadObject>>("KillStreakTop"); } void Unload() { Interface.Oxide.DataFileSystem.WriteObject("KillStreakBest", playerBestKillStreak); Interface.Oxide.DataFileSystem.WriteObject("KillStreakTop", serverBestKillStreak); } void OnPlayerDeath(BasePlayer player, HitInfo info) { if (info?.InitiatorPlayer != null && player != null && player.userID != 0 && IsValidSteamID(info.InitiatorPlayer.userID)) { if (info.InitiatorPlayer.userID != player.userID) { OnPlayerKill(info.InitiatorPlayer, player); } } OnPlayerDeathOrDisconnect(player.UserIDString, true); } bool IsValidSteamID(ulong userID) { string userIDString = userID.ToString(); return userIDString.StartsWith("7656") && userIDString.Length == 17; } void OnPlayerKill(BasePlayer killer, BasePlayer victim) { if (victim == null || (!config.CountNpcKills && !IsValidSteamID(victim.userID))) { return; } string playerId = killer.UserIDString; try { if (!playerKillStreak.ContainsKey(playerId)) { playerKillStreak[playerId] = 0; } playerKillStreak[playerId]++; int killStreak = playerKillStreak[playerId]; if (killStreak % killsToRestoreHealth == 0) { RestorePlayerHealth(killer); } if (rewardCommands.ContainsKey(killStreak)) { foreach (var rewardItem in rewardCommands[killStreak].Items) { var itemDef = ItemManager.FindItemDefinition(rewardItem.Item); if (itemDef == null) { Puts($"Item {rewardItem.Item} not found"); continue; } var item = ItemManager.CreateByItemID(itemDef.itemid, rewardItem.Amount, rewardItem.Skin); killer.inventory.GiveItem(item); } string message = rewardCommands[killStreak].Message.Replace("{id}", playerId).Replace("{killStreak}", killStreak.ToString()); if (rewardCommands[killStreak].BroadcastToServer) { PrintToChat($"{killer.displayName} {killStreak} kills, {message}"); } else { SendReply(killer, message); } } if (!playerBestKillStreak.ContainsKey(playerId) || playerKillStreak[playerId] > playerBestKillStreak[playerId]) { playerBestKillStreak[playerId] = playerKillStreak[playerId]; serverBestKillStreak[playerId] = new Tuple(killer.displayName, playerKillStreak[playerId]); Interface.Oxide.DataFileSystem.WriteObject("KillStreakBest", playerBestKillStreak); Interface.Oxide.DataFileSystem.WriteObject("KillStreakTop", serverBestKillStreak); } } catch (Exception ex) { Puts($"An error occurred: {ex.Message}\n{ex.StackTrace}"); } } [ChatCommand("ks")] void CmdKillStreak(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; } int currentKillStreak = playerKillStreak.ContainsKey(playerId) ? playerKillStreak[playerId] : 0; int bestKillStreak = playerBestKillStreak.ContainsKey(playerId) ? playerBestKillStreak[playerId] : 0; SendReply(player, $"Your current kill streak is {currentKillStreak}. Your best kill streak is {bestKillStreak}."); } [ChatCommand("kstop")] void CmdKillStreakTop(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 topKillStreaks = serverBestKillStreak.OrderByDescending(x => x.Value.Item2).Take(10); string message = "Top Kill Streaks:\n"; foreach (var killStreak in topKillStreaks) { string killStreakCount = killStreak.Value.Item2 < 10 ? " " + killStreak.Value.Item2.ToString() + " " : killStreak.Value.Item2.ToString() + " "; message += String.Format("{0} | {1}\n", killStreakCount, killStreak.Value.Item1); } SendReply(player, message); } void OnPlayerDisconnected(BasePlayer player) { if (player != null) { OnPlayerDeathOrDisconnect(player.UserIDString, false); } } public void OnPlayerDeathOrDisconnect(string playerId, bool isDeath) { try { if (isDeath && playerKillStreak.ContainsKey(playerId)) { playerKillStreak.Remove(playerId); } } catch (Exception ex) { Puts($"An error occurred: {ex.Message}\n{ex.StackTrace}"); } } public void RestorePlayerHealth(BasePlayer player) { try { player.Heal(player.MaxHealth()); player.SendNetworkUpdateImmediate(); } catch (Exception ex) { Puts($"An error occurred: {ex.Message}\n{ex.StackTrace}"); } } } }