C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using System.Linq;
using Oxide.Core;
using Oxide.Core.Libraries.Covalence;
namespace Oxide.Plugins
{
[Info("KarmaSystem", "Ryan", "1.1.0")]
[Description("Allows players to upvote/downvote other players")]
internal class KarmaSystem : CovalencePlugin
{
#region Config
private ConfigFile configFile;
public class ConfigFile
{
public Upvote UpvoteSettings { get; set; }
public Downvote DownvoteSettings { get; set; }
public Ranking Top { get; set; }
public Ranking Bottom { get; set; }
public bool EnableKarmaCommand { get; set; }
public float Cooldown { get; set; }
public bool OneVotePerPlayer { get; set; }
public static ConfigFile DefaultConfig()
{
return new ConfigFile
{
UpvoteSettings = new Upvote
{
Amount = 1,
EnableCommand = true
},
DownvoteSettings = new Downvote
{
Amount = 1,
EnableCommand = true
},
Top = new Ranking()
{
ShowAmount = 5
},
Bottom = new Ranking()
{
ShowAmount = 5,
},
EnableKarmaCommand = true,
Cooldown = 60,
OneVotePerPlayer = false
};
}
}
public class Upvote
{
public int Amount { get; set; }
public bool EnableCommand { get; set; }
}
public class Downvote
{
public int Amount { get; set; }
public bool EnableCommand { get; set; }
}
public class Ranking
{
public int ShowAmount { get; set; }
}
protected override void LoadDefaultConfig()
{
PrintWarning("Generating default configuration file...");
configFile = ConfigFile.DefaultConfig();
}
protected override void LoadConfig()
{
base.LoadConfig();
configFile = Config.ReadObject<ConfigFile>();
}
protected override void SaveConfig()
{
Config.WriteObject(configFile);
}
#endregion
#region Lang
private string Lang(string key, string id = null, params object[] args)
{
return string.Format(lang.GetMessage(key, this, id), args);
}
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
// Commands
["Cmd_Upvote"] =
"You've upvoted player <color=orange>{0}</color>, they now have <color=orange>{1}</color> karma",
["Cmd_Downvote"] =
"You've downvoted player <color=orange>{0}</color>, they now have <color=orange>{1}</color> karma",
["Cmd_Upvoted"] =
"You've been upvoted by player <color=orange>{0}</color>, you now have <color=orange>{1}</color> karma",
["Cmd_Downvoted"] =
"You've been downvoted by player <color=orange>{0}</color>, you now have <color=orange>{1}</color> karma",
["Cmd_Karma"] =
"You have <color=orange>{0}</color> karma and you have voted for <color=orange>{1}</color> players",
// Invalid args
["Cmd_InvalidArgs"] = "Invalid arguments.Usage: '/<color=orange>{0}</color> {1}'",
["Arg_Vote"] = "<player>",
["Arg_Ranking"] = "<top> OR <bottom>",
// FindPlayer
["FP_NoPlayers"] = "Found no players with input '<color=orange>{0}</color>'",
["FP_MultiplePlayers"] =
"Found the following players with input '<color=orange>{0}</color>', please refine your input.\n{1}",
// Cant use
["CU_Cooldown"] = "You can't vote for a player for another <color=orange>{0}</color> seconds",
["CU_AlreadyVoted"] = "You have already voted for player <color=orange>{0}</color>",
["CU_Yourself"] = "You can't vote for yourself, that's cheating!",
// Ranking
["Ranking_Info"] = "- <color=orange>{0}</color> (<color=orange>{1}</color> Karma)"
}, this);
}
#endregion
#region Data
private static StoredData storedData;
public class StoredData
{
public Dictionary<string, PlayerData> Players = new Dictionary<string, PlayerData>();
}
public class PlayerData
{
public PlayerData()
{
Karma = 0;
Cooldown = null;
Votes = new List<string>();
}
public int Karma { get; set; }
public DateTime? Cooldown { get; set; }
public List<string> Votes { get; set; }
}
public class Data
{
public static void AddNew(IPlayer player)
{
if (!Exists(player))
{
storedData.Players.Add(player.Id, new PlayerData());
Save();
}
}
public static void AddVoted(IPlayer player, string ID)
{
if (Exists(player))
{
storedData.Players[player.Id].Votes.Add(ID);
Save();
}
}
public static bool Exists(IPlayer player)
{
if (storedData.Players.ContainsKey(player.Id)) return true;
return false;
}
public static void Remove(IPlayer player)
{
if (Exists(player))
{
storedData.Players.Remove(player.Id);
Save();
}
}
public static void Clear()
{
storedData.Players.Clear();
Save();
}
public static void Save()
{
Interface.Oxide.DataFileSystem.WriteObject("KarmaSystem", storedData);
}
}
#endregion
#region Methods
private IPlayer FindPlayer(IPlayer player, string input)
{
var Players = new List<IPlayer>();
foreach (var target in players.FindPlayers(input))
if (target.IsConnected)
Players.Add(target);
if (Players.Count > 1)
{
player.Reply(Lang("FP_MultiplePlayers", player.Id, input,
string.Join(", ", Players.Select(x => x.Name).ToArray())));
return null;
}
if (Players.Count == 1)
{
var target = Players.First();
if (!Data.Exists(target))
Data.AddNew(target);
return target;
}
player.Reply(Lang("FP_NoPlayers", player.Id, input));
return null;
}
private bool CanVote(IPlayer player, IPlayer target)
{
if (player.Id == target.Id)
{
player.Reply(Lang("CU_Yourself", player.Id));
return false;
}
if (Data.Exists(player) && storedData.Players[player.Id].Cooldown != null && storedData.Players[player.Id].Cooldown.Value.AddMinutes(configFile.Cooldown) > DateTime.UtcNow)
{
player.Reply(Lang("CU_Cooldown", player.Id, (storedData.Players[player.Id].Cooldown.Value.AddMinutes(configFile.Cooldown) - DateTime.UtcNow).TotalSeconds));
return false;
}
if (Data.Exists(player) && storedData.Players[player.Id].Votes.Contains(target.Id) && configFile.OneVotePerPlayer)
{
player.Reply(Lang("CU_AlreadyVoted", player.Id, target.Name));
return false;
}
return true;
}
#endregion
#region API
int GetKarma(IPlayer player)
{
if (!Data.Exists(player))
Data.AddNew(player);
return storedData.Players[player.Id].Karma;
}
void AddKarma(IPlayer player, int amount)
{
if (!Data.Exists(player))
Data.AddNew(player);
storedData.Players[player.Id].Karma = storedData.Players[player.Id].Karma + amount;
Data.Save();
}
void RemoveKarma(IPlayer player, int amount)
{
if (!Data.Exists(player))
Data.AddNew(player);
storedData.Players[player.Id].Karma = storedData.Players[player.Id].Karma - amount;
Data.Save();
}
void AddPlayer(IPlayer player)
{
if (!Data.Exists(player))
return;
Data.AddNew(player);
}
void AddVoted(IPlayer player, string ID)
{
if (!Data.Exists(player))
Data.AddNew(player);
Data.AddVoted(player, ID);
}
void OnVoted(IPlayer player, IPlayer target, int amount)
{
storedData.Players[player.Id].Cooldown = DateTime.UtcNow;
Interface.Call("OnKarmaVote", player, target, amount);
}
#endregion
#region Hooks
private void Unload()
{
Data.Save();
}
private void Loaded()
{
SaveConfig();
storedData = Interface.Oxide.DataFileSystem.ReadObject<StoredData>(Name);
}
[Command("upvote")]
private void upvoteCmd(IPlayer player, string command, string[] args)
{
if (!configFile.UpvoteSettings.EnableCommand)
{
return;
}
if (args.Length == 0)
{
player.Reply(Lang("Cmd_InvalidArgs", player.Id, command, Lang("Arg_Vote", player.Id)));
return;
}
var target = FindPlayer(player, args[0]);
if (target != null && CanVote(player, target))
{
AddKarma(target, configFile.UpvoteSettings.Amount);
AddVoted(player, target.Id);
OnVoted(player, target, configFile.UpvoteSettings.Amount);
var karma = GetKarma(target);
player.Reply(Lang("Cmd_Upvote", player.Id, target.Name, karma));
target.Reply(Lang("Cmd_Upvoted", target.Id, player.Name, karma));
}
}
[Command("downvote")]
private void downvoteCmd(IPlayer player, string command, string[] args)
{
if (!configFile.DownvoteSettings.EnableCommand)
{
return;
}
if (args.Length == 0)
{
player.Reply(Lang("Cmd_InvalidArgs", player.Id, command, Lang("Arg_Vote", player.Id)));
return;
}
var target = FindPlayer(player, args[0]);
if (target != null && CanVote(player, target))
{
RemoveKarma(target, configFile.DownvoteSettings.Amount);
AddVoted(player, target.Id);
OnVoted(player, target, configFile.DownvoteSettings.Amount);
var karma = GetKarma(target);
player.Reply(Lang("Cmd_Downvote", player.Id, target.Name, karma));
target.Reply(Lang("Cmd_Downvoted", target.Id, player.Name, karma));
}
}
[Command("karma")]
private void karmaCmd(IPlayer player, string command, string[] args)
{
if (!configFile.EnableKarmaCommand)
{
return;
}
if (args.Length == 0)
{
player.Reply(Lang("Cmd_Karma", player.Id, GetKarma(player), storedData.Players[player.Id].Votes.Count));
return;
}
if (args.Length == 1)
{
switch (args[0])
{
case "top":
foreach (var info in storedData.Players.OrderByDescending(x => x.Value.Karma).Take(configFile.Top.ShowAmount))
player.Reply(Lang("Ranking_Info", player.Id, players.FindPlayerById(info.Key).Name, info.Value.Karma));
return;
case "bottom":
foreach (var info in storedData.Players.OrderByDescending(x => x.Value.Karma).Reverse().Take(configFile.Bottom.ShowAmount))
player.Reply(Lang("Ranking_Info", player.Id, players.FindPlayerById(info.Key).Name, info.Value.Karma));
return;
default:
var target = FindPlayer(player, args[0]);
if (target != null)
{
if(!Data.Exists(target))
Data.AddNew(target);
player.Reply(Lang("Ranking_Info", player.Id, target.Name, storedData.Players[target.Id].Karma));
}
return;
}
}
player.Reply(Lang("Cmd_InvalidArgs", player.Id, command, Lang("Arg_Ranking", player.Id)));
}
#endregion
}
}