2018-10-15 20:51:04 -04:00
|
|
|
|
using SharedLibraryCore;
|
2018-11-05 22:01:29 -05:00
|
|
|
|
using SharedLibraryCore.Database.Models;
|
2018-10-15 20:51:04 -04:00
|
|
|
|
using SharedLibraryCore.Objects;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace IW4ScriptCommands.Commands
|
|
|
|
|
{
|
|
|
|
|
class Balance
|
2018-10-25 09:14:39 -04:00
|
|
|
|
{
|
2018-10-15 20:51:04 -04:00
|
|
|
|
private class TeamAssignment
|
|
|
|
|
{
|
|
|
|
|
public IW4MAdmin.Plugins.Stats.IW4Info.Team CurrentTeam { get; set; }
|
|
|
|
|
public int Num { get; set; }
|
|
|
|
|
public IW4MAdmin.Plugins.Stats.Models.EFClientStatistics Stats { get; set; }
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-05 22:01:29 -05:00
|
|
|
|
public static string GetTeamAssignments(EFClient client, bool isDisconnect, Server server, string teamsString = "")
|
2018-10-15 20:51:04 -04:00
|
|
|
|
{
|
|
|
|
|
var scriptClientTeams = teamsString.Split(';', StringSplitOptions.RemoveEmptyEntries)
|
|
|
|
|
.Select(c => c.Split(','))
|
|
|
|
|
.Select(c => new TeamAssignment()
|
|
|
|
|
{
|
|
|
|
|
CurrentTeam = (IW4MAdmin.Plugins.Stats.IW4Info.Team)Enum.Parse(typeof(IW4MAdmin.Plugins.Stats.IW4Info.Team), c[1]),
|
2018-11-05 22:01:29 -05:00
|
|
|
|
Num = server.GetClientsAsList().FirstOrDefault(p => p.ClientNumber == Int32.Parse(c[0]))?.ClientNumber ?? -1,
|
|
|
|
|
Stats = IW4MAdmin.Plugins.Stats.Plugin.Manager.GetClientStats(server.Clients.FirstOrDefault(p => p.ClientNumber == Int32.Parse(c[0])).ClientId, server.GetHashCode())
|
2018-10-15 20:51:04 -04:00
|
|
|
|
})
|
|
|
|
|
.ToList();
|
|
|
|
|
|
|
|
|
|
// at least one team is full so we can't balance
|
2018-10-25 09:14:39 -04:00
|
|
|
|
if (scriptClientTeams.Count(ct => ct.CurrentTeam == IW4MAdmin.Plugins.Stats.IW4Info.Team.Axis) >= Math.Floor(server.MaxClients / 2.0)
|
|
|
|
|
|| scriptClientTeams.Count(ct => ct.CurrentTeam == IW4MAdmin.Plugins.Stats.IW4Info.Team.Allies) >= Math.Floor(server.MaxClients / 2.0))
|
2018-10-15 20:51:04 -04:00
|
|
|
|
{
|
2018-10-25 09:14:39 -04:00
|
|
|
|
// E.Origin?.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_BALANCE_FAIL"]);
|
2018-10-15 20:51:04 -04:00
|
|
|
|
return string.Empty;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
List<string> teamAssignments = new List<string>();
|
|
|
|
|
|
2018-11-05 22:01:29 -05:00
|
|
|
|
var _c = server.GetClientsAsList();
|
2018-10-25 09:14:39 -04:00
|
|
|
|
if (isDisconnect && client != null)
|
|
|
|
|
{
|
|
|
|
|
_c = _c.Where(c => c.ClientNumber != client.ClientNumber).ToList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var activeClients = _c.Select(c => new TeamAssignment()
|
2018-10-15 20:51:04 -04:00
|
|
|
|
{
|
|
|
|
|
Num = c.ClientNumber,
|
2018-10-25 09:14:39 -04:00
|
|
|
|
Stats = IW4MAdmin.Plugins.Stats.Plugin.Manager.GetClientStats(c.ClientId, server.GetHashCode()),
|
|
|
|
|
CurrentTeam = IW4MAdmin.Plugins.Stats.Plugin.Manager.GetClientStats(c.ClientId, server.GetHashCode()).Team
|
2018-10-15 20:51:04 -04:00
|
|
|
|
})
|
|
|
|
|
.Where(c => scriptClientTeams.FirstOrDefault(sc => sc.Num == c.Num)?.CurrentTeam != IW4MAdmin.Plugins.Stats.IW4Info.Team.Spectator)
|
|
|
|
|
.Where(c => c.CurrentTeam != scriptClientTeams.FirstOrDefault(p => p.Num == c.Num)?.CurrentTeam)
|
|
|
|
|
.OrderByDescending(c => c.Stats.Performance)
|
|
|
|
|
.ToList();
|
|
|
|
|
|
|
|
|
|
var alliesTeam = scriptClientTeams
|
|
|
|
|
.Where(c => c.CurrentTeam == IW4MAdmin.Plugins.Stats.IW4Info.Team.Allies)
|
|
|
|
|
.Where(c => activeClients.Count(t => t.Num == c.Num) == 0)
|
|
|
|
|
.ToList();
|
|
|
|
|
|
|
|
|
|
var axisTeam = scriptClientTeams
|
|
|
|
|
.Where(c => c.CurrentTeam == IW4MAdmin.Plugins.Stats.IW4Info.Team.Axis)
|
|
|
|
|
.Where(c => activeClients.Count(t => t.Num == c.Num) == 0)
|
|
|
|
|
.ToList();
|
|
|
|
|
|
|
|
|
|
while (activeClients.Count() > 0)
|
|
|
|
|
{
|
|
|
|
|
int teamSizeDifference = alliesTeam.Count - axisTeam.Count;
|
|
|
|
|
double performanceDisparity = alliesTeam.Count > 0 ? alliesTeam.Average(t => t.Stats.Performance) : 0 -
|
|
|
|
|
axisTeam.Count > 0 ? axisTeam.Average(t => t.Stats.Performance) : 0;
|
|
|
|
|
|
|
|
|
|
if (teamSizeDifference == 0)
|
|
|
|
|
{
|
|
|
|
|
if (performanceDisparity == 0)
|
|
|
|
|
{
|
|
|
|
|
alliesTeam.Add(activeClients.First());
|
|
|
|
|
activeClients.RemoveAt(0);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (performanceDisparity > 0)
|
|
|
|
|
{
|
|
|
|
|
axisTeam.Add(activeClients.First());
|
|
|
|
|
activeClients.RemoveAt(0);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
alliesTeam.Add(activeClients.First());
|
|
|
|
|
activeClients.RemoveAt(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (teamSizeDifference > 0)
|
|
|
|
|
{
|
|
|
|
|
if (performanceDisparity > 0)
|
|
|
|
|
{
|
|
|
|
|
axisTeam.Add(activeClients.First());
|
|
|
|
|
activeClients.RemoveAt(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
axisTeam.Add(activeClients.Last());
|
|
|
|
|
activeClients.RemoveAt(activeClients.Count - 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (performanceDisparity > 0)
|
|
|
|
|
{
|
|
|
|
|
alliesTeam.Add(activeClients.First());
|
|
|
|
|
activeClients.RemoveAt(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
alliesTeam.Add(activeClients.Last());
|
|
|
|
|
activeClients.RemoveAt(activeClients.Count - 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
alliesTeam = alliesTeam.OrderByDescending(t => t.Stats.Performance)
|
|
|
|
|
.ToList();
|
|
|
|
|
|
|
|
|
|
axisTeam = axisTeam.OrderByDescending(t => t.Stats.Performance)
|
|
|
|
|
.ToList();
|
|
|
|
|
|
|
|
|
|
while (Math.Abs(alliesTeam.Count - axisTeam.Count) > 1)
|
|
|
|
|
{
|
|
|
|
|
int teamSizeDifference = alliesTeam.Count - axisTeam.Count;
|
|
|
|
|
double performanceDisparity = alliesTeam.Count > 0 ? alliesTeam.Average(t => t.Stats.Performance) : 0 -
|
|
|
|
|
axisTeam.Count > 0 ? axisTeam.Average(t => t.Stats.Performance) : 0;
|
|
|
|
|
|
|
|
|
|
if (teamSizeDifference > 0)
|
|
|
|
|
{
|
|
|
|
|
if (performanceDisparity > 0)
|
|
|
|
|
{
|
|
|
|
|
axisTeam.Add(alliesTeam.First());
|
|
|
|
|
alliesTeam.RemoveAt(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
axisTeam.Add(alliesTeam.Last());
|
|
|
|
|
alliesTeam.RemoveAt(axisTeam.Count - 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (performanceDisparity > 0)
|
|
|
|
|
{
|
|
|
|
|
alliesTeam.Add(axisTeam.Last());
|
|
|
|
|
axisTeam.RemoveAt(axisTeam.Count - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
alliesTeam.Add(axisTeam.First());
|
|
|
|
|
axisTeam.RemoveAt(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (var assignment in alliesTeam)
|
|
|
|
|
{
|
|
|
|
|
teamAssignments.Add($"{assignment.Num},2");
|
|
|
|
|
assignment.Stats.Team = IW4MAdmin.Plugins.Stats.IW4Info.Team.Allies;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (var assignment in axisTeam)
|
|
|
|
|
{
|
|
|
|
|
teamAssignments.Add($"{assignment.Num},3");
|
|
|
|
|
assignment.Stats.Team = IW4MAdmin.Plugins.Stats.IW4Info.Team.Axis;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//if (alliesTeam.Count(ac => scriptClientTeams.First(sc => sc.Num == ac.Num).CurrentTeam != ac.CurrentTeam) == 0 &&
|
|
|
|
|
// axisTeam.Count(ac => scriptClientTeams.First(sc => sc.Num == ac.Num).CurrentTeam != ac.CurrentTeam) == 0)
|
|
|
|
|
//{
|
|
|
|
|
// //E.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_BALANCE_FAIL_BALANCED"]);
|
|
|
|
|
// return string.Empty;
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
//if (E.Origin?.Level > Player.Permission.Administrator)
|
|
|
|
|
//{
|
|
|
|
|
// E.Origin.Tell($"Allies Elo: {(alliesTeam.Count > 0 ? alliesTeam.Average(t => t.Stats.Performance) : 0)}");
|
|
|
|
|
// E.Origin.Tell($"Axis Elo: {(axisTeam.Count > 0 ? axisTeam.Average(t => t.Stats.Performance) : 0)}");
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
//E.Origin.Tell("Balance command sent");
|
|
|
|
|
string args = string.Join(",", teamAssignments);
|
|
|
|
|
return args;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|