C#:
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<string, int> playerKillStreak = new SortedDictionary<string, int>();
private SortedDictionary<string, int> playerBestKillStreak = new SortedDictionary<string, int>();
private SortedDictionary<string, Tuple<string, int>> serverBestKillStreak = new SortedDictionary<string, Tuple<string, int>>();
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<RewardItem> Items { get; set; }
public string Message { get; set; }
public bool BroadcastToServer { get; set; }
}
private SortedDictionary<int, Reward> rewardCommands = new SortedDictionary<int, Reward>();
public class Configuration
{
public SortedDictionary<int, Reward> 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<int, Reward>(),
KillsToRestoreHealth = 5,
Version = CurrentVersion,
CountNpcKills = false
};
plugin.Config.WriteObject(config, true);
return config;
}
return plugin.Config.ReadObject<Configuration>(fileName);
}
}
private bool UpdateConfiguration(Configuration config)
{
if (config.Version < CurrentVersion)
{
config.Version = CurrentVersion;
config.RewardCommands = new SortedDictionary<int, Reward>();
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<int, Reward>
{
{ 2, new Reward { Items = new List<RewardItem>(), Message = "<color=#ff686b>Double Kill!</color>", BroadcastToServer = false } },
{ 3, new Reward { Items = new List<RewardItem>(), Message = "<color=#ff686b>Triple Kill!</color>", BroadcastToServer = false } },
{ 5, new Reward { Items = new List<RewardItem>(), Message = "<color=#ff686b>Pentakill!</color>", BroadcastToServer = true } },
{ 10, new Reward { Items = new List<RewardItem>(), Message = "<color=#ff686b>Decimation!</color>", BroadcastToServer = true } },
{ 15, new Reward { Items = new List<RewardItem>(), Message = "<color=#ff686b>Deadly!</color>", BroadcastToServer = true } },
{ 20, new Reward { Items = new List<RewardItem>(), Message = "<color=#ff686b>Monsterkill!</color>", BroadcastToServer = true } },
{ 30, new Reward { Items = new List<RewardItem>(), Message = "<color=#ff686b>Megakill!</color>", BroadcastToServer = true } },
{ 40, new Reward { Items = new List<RewardItem>(), Message = "<color=#ff686b>Massacre!</color>", BroadcastToServer = true } },
{ 50, new Reward { Items = new List<RewardItem>(), Message = "<color=#ff686b>Unstoppable!</color>", BroadcastToServer = true } },
{ 60, new Reward { Items = new List<RewardItem>(), Message = "<color=#ff686b>Ultrakill!</color>", BroadcastToServer = true } },
{ 70, new Reward { Items = new List<RewardItem>(), Message = "<color=#ff686b>Annihilation!</color>", BroadcastToServer = true } },
{ 80, new Reward { Items = new List<RewardItem>(), Message = "<color=#ff686b>Epic!</color>", BroadcastToServer = true } },
{ 90, new Reward { Items = new List<RewardItem>(), Message = "<color=#ff686b>Godlike!</color>", BroadcastToServer = true } },
{ 100, new Reward { Items = new List<RewardItem>(), Message = "<color=#ff686b>LEGEND!!!!!</color>", 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<SortedDictionary<string, int>>("KillStreakBest");
serverBestKillStreak = Interface.Oxide.DataFileSystem.ReadObject<SortedDictionary<string, Tuple<string, int>>>("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} <color=#ff686b>{killStreak}</color> kills, {message}");
}
else
{
SendReply(killer, message);
}
}
if (!playerBestKillStreak.ContainsKey(playerId) || playerKillStreak[playerId] > playerBestKillStreak[playerId])
{
playerBestKillStreak[playerId] = playerKillStreak[playerId];
serverBestKillStreak[playerId] = new Tuple<string, int>(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 <color=#ff686b>{currentKillStreak}</color>. Your best kill streak is <color=#ff686b>{bestKillStreak}</color>.");
}
[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 = "<color=#ff686b>Top Kill Streaks:</color>\n";
foreach (var killStreak in topKillStreaks)
{
string killStreakCount = killStreak.Value.Item2 < 10 ? " " + killStreak.Value.Item2.ToString() + " " : killStreak.Value.Item2.ToString() + " ";
message += String.Format("<color=#ff686b>{0}</color> | {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}");
}
}
}
}