C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using System.Linq;
using Oxide.Core.Libraries.Covalence;
namespace Oxide.Plugins
{
// TODO LIST
// Nothing, yet.[Info("VoteKick", "Kappasaurus", "1.0.2")]
class VoteKick : CovalencePlugin
{
#region Variables
private List<string> voted = new List<string>();
private bool activeVote;
private int votes = 0;
private IPlayer target;
private Timer voteTimer;
// CONFIG RELATED
private float percentageRequired = 0.6f;
private int playersRequired = 10;
#endregion
#region Hooks
void Init()
{
permission.RegisterPermission("votekick.able", this);
LoadConfig();
}
void OnUserDisconnected(IPlayer player)
{
if (target != null && activeVote && player.Id == target.Id)
{
server.Broadcast(lang.GetMessage("Target Disconnected", this));
activeVote = false;
voteTimer?.Destroy();
voted.Clear();
target = null;
}
}
#endregion
#region Command
[Command("votekick")]
void VoteKickCmd(IPlayer player, string command, string[] args)
{
if (!player.HasPermission("votekick.able"))
{
player.Message(lang.GetMessage("No Permission", this, player.Id));
return;
}
if (players.Connected.Count() < playersRequired)
{
player.Message(lang.GetMessage("Not Enough Players", this, player.Id));
return;
}
if (activeVote)
{
player.Message(lang.GetMessage("Other Vote Open", this, player.Id));
return;
}
if (args.Length == 0)
{
player.Message(lang.GetMessage("No Target", this, player.Id));
return;
}
target = covalence.Players.FindPlayer(args[0]);
if (target == null || !target.IsConnected)
{
player.Message(lang.GetMessage("Target Not Found", this, player.Id));
return;
}
if (player.Equals(target))
{
player.Message(lang.GetMessage("Vote Self", this, player.Id));
return;
}
if (target.IsAdmin)
{
player.Message(lang.GetMessage("No Permission", this, player.Id));
return;
}
activeVote = true;
server.Broadcast(lang.GetMessage("Kick Started", this).Replace("{player}", player.Name).Replace("{target}", target.Name));
voteTimer = timer.Once(600f, () =>
{
if (!activeVote)
return;
activeVote = false;
target = null;
server.Broadcast(lang.GetMessage("Timed Out", this));
voted.Clear();
});
}
[Command("vote")]
void VoteCmd(IPlayer player, string command, string[] args)
{
var requiredVotes = players.Connected.Count() * percentageRequired;
if (!activeVote)
{
player.Message(lang.GetMessage("No Vote Open", this, player.Id));
return;
}
if (player.Equals(target))
{
player.Message(lang.GetMessage("Vote Self", this, player.Id));
return;
}
if (voted.Contains(player.Id))
{
player.Message(lang.GetMessage("Already Voted", this, player.Id));
return;
}
voted.Add(player.Id);
player.Message(lang.GetMessage("Vote Placed", this, player.Id));
if (voted.Count >= requiredVotes)
{
server.Broadcast(lang.GetMessage("Vote Successful", this));
target.Kick(lang.GetMessage("Kick Message", this, player.Id));
activeVote = false;
target = null;
voteTimer?.Destroy();
voted.Clear();
}
}
#endregion
#region Configuration
private new void LoadConfig()
{
GetConfig(ref percentageRequired, "Percentage required");
GetConfig(ref playersRequired, "Players required");
SaveConfig();
}
protected override void LoadDefaultConfig() => PrintWarning("Generating new configuration file...");
#endregion
#region Helpers
private void GetConfig<T>(ref T variable, params string[] path)
{
if (path.Length == 0)
return;
if (Config.Get(path) == null)
{
Config.Set(path.Concat(new object[] { variable }).ToArray());
PrintWarning($"Added field to config: {string.Join("/", path)}");
}
variable = (T)Convert.ChangeType(Config.Get(path), typeof(T));
}
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["Kick Message"] = "You have been voted out.",
["Vote Self"] = "<size=12>Error, you can't vote to kick yourself.</size>",
["Timed Out"] = "<size=12>Error, not enough votes, vote cancelled.</size>",
["Vote Successful"] = "<size=12>Vote successful.</size>",
["Not Enough Players"] = "<size=12>Error, not enough players online.</size>",
["No Arguments"] = "<size=12>Error, no arguments supplied.</size>",
["No Target"] = "<size=12>Error, no target supplied.</size>",
["Target Not Found"] = "<size=12>Error, player not found, try more specific terms.</size>",
["Already Voted"] = "<size=12>Error, you already voted.</size>",
["Vote Placed"] = "<size=12>Vote sucessfully placed.</size>",
["No Vote Open"] = "<size=12>Error, no vote open.</size>",
["No Permission"] = "<size=12>Error, no permission.</size>",
["Kick Started"] = "<size=12>{player} called a kick vote on {target}.</size> Use /vote to vote yes.",
["Target Disconnected"] = "<size=12>Vote cancelled, target disconnected.</size>",
["Another Vote Open"] = "<size=12>Error, another vote is already open.</size>"
}, this);
}
#endregion
}
}