here is iAegle code with many modifications done by me. I think everything is working great. Running it in my server 1.4.382. If you find any bugs or have any suggestion, I appreciate it.
ps: it was the first time I used C#
commands: !status !votekick !vote
sv_config.ini:
ps: it was the first time I used C#

commands: !status !votekick !vote
sv_config.ini:
Code:
[VOTEKICK]
cooldown=60
votetime=45
votemsginterval=4Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Addon;
using System.Threading;
namespace mw3_votekick
{
public class VoteKick : CPlugin
{
Vote vote;
int Interval;
int VoteTime;
int votemsginterval;
List<int> validPN;
List<ServerClient> players = new List<ServerClient>();
public override void OnServerFrame()
{
if (Interval > 0)
Interval--;
if (VoteTime > 0)
{
if (VoteTime % votemsginterval == 0)
{
foreach (ServerClient player in players)
{
if (player.Ping < 999 && player.Ping > 0)
{
iPrintLnBold("^1(" + VoteTime / 50 + "s) ^5votekick player ^7" + vote.Client.Name + "^5 in progress. ^3!vote [^2Y^3/^1N^3] ^0| ^2(" + vote.Agree.Count + ")Y ^1(" + (validPN.Count - vote.Agree.Count) + ")N", player);
}
}
}
VoteTime--;
if (VoteTime == 0 && vote.InProgress)
{
if (((vote.Agree.Count / validPN.Count) * 100) >= 60)
{
ServerCommand("kickclient " + vote.Client.ClientNum);
ServerSay("^3Player " + vote.Client.Name + " got kicked" + vote.Reason, true);
}
else
ServerSay("^3Not enough players agree to kick " + vote.Client.Name, true);
//reset vars
players.Clear();
validPN.Clear();
VoteTime = 0;
vote.Client = null;
vote.Agree.Clear();
vote.InProgress = false;
vote.Reason = "";
//set cooldown timer
Interval = Convert.ToInt32(GetServerCFG("VOTEKICK", "cooldown", "30")) * 50;
}
}
}
public override void OnServerLoad()
{
ServerPrint("VoteKick plugin loaded");
votemsginterval = Convert.ToInt32(GetServerCFG("VOTEKICK", "votemsginterval", "5")) * 50;
}
public override ChatType OnSay(string Message, ServerClient Client)
{
string lowMsg = Message.ToLower();
int playerNumber = -1;
int tmpPN = -1;
if (lowMsg.StartsWith("!votekick"))
{
if (Interval > 0)
{
TellClient(Client.ClientNum, "^3You can't start a vote now! wait " + Interval / 50 + " seconds.", true);
return ChatType.ChatNone;
}
if (players.Count <= 0)
{
TellClient(Client.ClientNum, "^3You must use ^2!status ^3first to see the number of the player you want to kick", true);
}
else if (lowMsg.Length <= 12)
{
TellClient(Client.ClientNum, "^3Usage: ^2!votekick [Player Number] [Reason]", true);
}
else if (vote.InProgress)
{
TellClient(Client.ClientNum, "^3There's already a vote in progress!", true);
}
else
{
if (int.TryParse(Message.Substring(10).Split(' ')[0], out tmpPN) == false)
{
TellClient(Client.ClientNum, "^1Invalid Player Number. Please enter a valid number.", true);
}
else if (!validPN.Contains(tmpPN))
{
TellClient(Client.ClientNum, "^1Invalid Player Number. Please enter a valid number.", true);
}
else
{
playerNumber = tmpPN;
string reason = "";
if (!Message.Substring(10).Split(' ')[1].Equals(""))
{
reason = " ^3for " + Message.Substring(10).Split(' ')[1];
}
ServerClient KickClient = GetClient(playerNumber);
ServerSay("^7" + Client.Name + " ^3wants to kick ^7" + KickClient.Name + reason + ". Please vote: ^2Y^3es or ^1N^3o", true);
vote.Agree = new List<string>();
vote.Client = KickClient;
vote.Agree.Add(Client.XUID);
vote.InProgress = true;
vote.Reason = reason;
VoteTime = Convert.ToInt32(GetServerCFG("VOTEKICK", "votetime", "15")) * 50;
}
}
return ChatType.ChatNone;
}
else if (lowMsg.StartsWith("!vote"))
{
if (!vote.InProgress)
{
TellClient(Client.ClientNum, "^3There is currently no vote in progress.", true);
}
else if (lowMsg.Length <= 6)
TellClient(Client.ClientNum, "^3Usage: ^2!vote [^2Y^0/^1N^3]", true);
else if ((lowMsg.Substring(6) == "y" || lowMsg.Substring(6) == "yes"))
{
if (!vote.Agree.Contains(Client.XUID))
{
vote.Agree.Add(Client.XUID);
TellClient(Client.ClientNum, "^3You agreed with kicking ^7" + vote.Client.Name, true);
}
else
{
TellClient(Client.ClientNum, "^3You already agreed with kicking ^7" + vote.Client.Name, true);
}
}
else if ((lowMsg.Substring(6) == "n" || lowMsg.Substring(6) == "no") && vote.Agree.Contains(Client.XUID))
{
vote.Agree.Remove(Client.XUID);
TellClient(Client.ClientNum, "^3You voted against kicking ^7" + vote.Client.Name, true);
}
else
{
TellClient(Client.ClientNum, "^3Invalid argument \"" + lowMsg.Substring(6) + "\"", true);
TellClient(Client.ClientNum, "^3use ^2Y ^3or ^1N", true);
}
return ChatType.ChatNone;
}
else if (lowMsg.Equals("!status"))
{
Thread thread = new Thread(PrintPlayerList);
thread.Start(Client);
return ChatType.ChatNone;
}
return ChatType.ChatContinue;
}
public struct Vote
{
public bool InProgress;
public string Reason;
public ServerClient Client;
public List<string> Agree;
}
public void PrintPlayerList(object cli)
{
ServerClient Client = (ServerClient)cli;
players = GetClients();
TellClient(Client.ClientNum, "^2[Player Number] ^0- ^3[Player Name]", true);
Thread.Sleep(1000);
validPN = new List<int>();
foreach (ServerClient player in players)
{
if (player.Ping < 999 && player.Ping > 0)
{
TellClient(Client.ClientNum, "^2" + player.ClientNum + " ^0- " + "^3" + player.Name, true);
validPN.Add(player.ClientNum);
Thread.Sleep(1000);
}
}
}
}
}



![[Image: lQDUjba.jpg]](http://i.imgur.com/lQDUjba.jpg)