PRoConEvents.MULTIbalancer.FastBalance C# (CSharp) Method

FastBalance() private method

private FastBalance ( String trigger ) : void
trigger String
return void
        private void FastBalance(String trigger)
        {
            /* Useful variables */

            PlayerModel player = null;
            String simpleMode = String.Empty;
            PerModeSettings perMode = GetPerModeSettings();
            int winningTeam = 0;
            int losingTeam = 0;
            int biggestTeam = 0;
            int smallestTeam = 0;
            int[] ascendingSize = null;
            int[] descendingTickets = null;
            String strongMsg = String.Empty;
            int diff = 0;
            DateTime now = DateTime.Now;
            String log = String.Empty;
            int level = 6;
            int adj = 1;

            /* Sanity checks */

            if (fServerInfo == null) {
            return;
            }

            if (fGameState != GameState.Playing) {
            return;
            }

            if (IsNonBalancingMode()) {
            return;
            }

            if (trigger.Contains("Kill")) {
            level = 8;
            adj = 0;
            }

            if (fLastFastMoveTimestamp != DateTime.MinValue && now.Subtract(fLastFastMoveTimestamp).TotalSeconds < 25) {
            if (DebugLevel >= (level + adj)) DebugFast("Too soon to check for fast balance again, wait another " + (25.0 - now.Subtract(fLastFastMoveTimestamp).TotalSeconds).ToString("F1") + " seconds");
            return;
            }

            Speed balanceSpeed = GetBalanceSpeed(perMode);

            if (balanceSpeed == Speed.Stop) {
            if (DebugLevel >= (level + adj)) DebugFast("Speed is Stop, fast balance check skipped. " + trigger + " was trigger"); // DebugBalance on purpose to get repeat filtering
            return;
            }

            int totalPlayerCount = TotalPlayerCount();

            if (DebugLevel >= (level + adj)) DebugFast(trigger + "Checking if fast balance is needed, " + totalPlayerCount + " players");

            if (totalPlayerCount >= (MaximumServerSize-1)) {
            if (DebugLevel >= (level + adj)) DebugFast("Server is full, no balancing or unstacking will be attempted!");
            return;
            }

            if (totalPlayerCount >= (perMode.MaxPlayers-1)) {
            if (DebugLevel >= (level + adj)) DebugFast("Server is full by per-mode Max Players, no balancing or unstacking will be attempted!");
            return;
            }

            int floorPlayers = (perMode.EnableLowPopulationAdjustments) ? 4 : 5;
            if (totalPlayerCount < floorPlayers) {
            if (DebugLevel >= (level + adj)) DebugFast("Not enough players in server, minimum is " + floorPlayers);
            return;
            }

            if (totalPlayerCount > 0) {
            AnalyzeTeams(out diff, out ascendingSize, out descendingTickets, out biggestTeam, out smallestTeam, out winningTeam, out losingTeam);
            }

            // Adjust speed to Fast?
            if (balanceSpeed != Speed.Fast) {
            if (diff > MaxFastDiff()) {
            balanceSpeed = Speed.Fast;
            }
            }
            if (balanceSpeed != Speed.Fast || diff <= MaxFastDiff()) {
            if (diff > 1 && DebugLevel >= level) DebugFast("Fast balance not active, diff is only " + diff + ", requires more than " + MaxFastDiff());
            return;
            }

            // Prepare for player selection
            if (smallestTeam < 1) {
            DebugFast("Cannot determine smallest team: " + smallestTeam);
            return;
            }
            List<PlayerModel> big = new List<PlayerModel>();
            List<PlayerModel> tmp = GetTeam(biggestTeam);
            if (tmp == null || tmp.Count < 1 || biggestTeam < 1) {
            DebugFast("Cannot determine biggest team: " + biggestTeam);
            return;
            }
            big.AddRange(tmp);
            tmp = new List<PlayerModel>();
            foreach (PlayerModel p in big) {
            if (p == null) continue;
            if (fGameVersion != GameVersion.BF3 && p.Role >= 0 && p.Role < ROLE_NAMES.Length && p.Role != ROLE_PLAYER) {
            if (DebugLevel >= 7) DebugFast("Excluding ^b" + p.Name + "^n, role is " + ROLE_NAMES[p.Role]);
            continue;
            } else if (OnWhitelist && CheckWhitelist(p, WL_BALANCE)) { // exclude if on whitelist
            if (DebugLevel >= 7) DebugFast("Excluding ^b" + p.FullName + "^n: on Whitelist");
            continue;
            } else if (p.MovedByMBTimestamp != DateTime.MinValue) { // exclude if moved recently
            double mins = now.Subtract(p.MovedByMBTimestamp).TotalMinutes;
            if (mins < MinutesAfterBeingMoved) {
                if (DebugLevel >= 7) DebugFast("Excluding ^b" + p.Name + "^n: last move was " + mins.ToString("F0") + " minutes ago, less than required " + MinutesAfterBeingMoved.ToString("F0") + " minutes");
                continue;
            } else {
                // reset
                p.MovedByMBTimestamp = DateTime.MinValue;
            }
            }

            tmp.Add(p);
            }
            big = tmp;

            // Select player
            if (DebugLevel >= 7) ConsoleDebug("FastBalance selecting player");
            if (big.Count < 1) {
            if (DebugLevel >= level) DebugFast("All players on " + GetTeamName(biggestTeam) + " team were excluded, unable to select the " + SelectFastBalanceBy + " player");
            return;
            }
            String kstat = String.Empty;
            switch (SelectFastBalanceBy) {
            case ForceMove.Weakest: {
            switch (perMode.DetermineStrongPlayersBy) {
                case DefineStrong.RoundScore:
                    big.Sort(DescendingRoundScore);
                    kstat = "S";
                    break;
                case DefineStrong.RoundSPM:
                    big.Sort(DescendingRoundSPM);
                    kstat = "SPM";
                    break;
                case DefineStrong.RoundKills:
                    big.Sort(DescendingRoundKills);
                    kstat = "K";
                    break;
                case DefineStrong.RoundKDR:
                    big.Sort(DescendingRoundKDR);
                    kstat = "KDR";
                    break;
                case DefineStrong.PlayerRank:
                    big.Sort(DescendingPlayerRank);
                    kstat = "R";
                    break;
                case DefineStrong.RoundKPM:
                    big.Sort(DescendingRoundKPM);
                    kstat = "KPM";
                    break;
                case DefineStrong.BattlelogSPM:
                    big.Sort(DescendingSPM);
                    kstat = "bSPM";
                    break;
                case DefineStrong.BattlelogKDR:
                    big.Sort(DescendingKDR);
                    kstat = "bKDR";
                    break;
                case DefineStrong.BattlelogKPM:
                    big.Sort(DescendingKPM);
                    kstat = "bKPM";
                    break;
                default:
                    big.Sort(DescendingRoundScore);
                    break;
            }

            // Select weakest
            player = big[big.Count-1];
            DebugFast("Selected WEAKEST player ^b" + player.FullName + "^n, " + kstat + ": " + GetPlayerStat(player, perMode.DetermineStrongPlayersBy).ToString("F1"));
            break;
            }

            case ForceMove.Newest: {
            // Descending by elapsed join time
            big.Sort(delegate(PlayerModel lhs, PlayerModel rhs) {
                if (lhs == null) {
                    return ((rhs == null) ? 0 : -1);
                } else if (rhs == null) {
                    return ((lhs == null) ? 0 : 1);
                }
                double lTime = GetPlayerJoinedTimeSpan(lhs).TotalSeconds;
                double rTime = GetPlayerJoinedTimeSpan(rhs).TotalSeconds;
                if (lTime < rTime) return 1;
                if (lTime > rTime) return -1;
                return 0;
            });
            // Select newest
            player = big[big.Count-1];
            DebugFast("Selected NEWEST player ^b" + player.FullName + "^n, joined " + GetPlayerJoinedTimeSpan(player).TotalMinutes.ToString("F1") + " minutes ago");
            break;
            }

            case ForceMove.Random: {
            Random rnd = new Random();
            player = big[rnd.Next(big.Count)];
            DebugFast("Selected RANDOM player ^b" + player.FullName);
            break;
            }
            }

            /* Move for fast balance */

            if (DebugLevel >= 7) ConsoleDebug("Move for fast balance");

            int origTeam = player.Team;
            String origName = GetTeamName(player.Team);
            int lastMoveFrom = player.LastMoveFrom;

            if (lastMoveFrom != 0) {
            origTeam = lastMoveFrom;
            origName = GetTeamName(origTeam);
            }

            MoveInfo move = new MoveInfo(player.Name, player.Tag, origTeam, origName, smallestTeam, GetTeamName(smallestTeam), 0);
            move.For = MoveType.Balance;
            // private message to player before getting killed
            move.Format(this, ChatMovedForBalance, false, true);
            move.Format(this, YellMovedForBalance, true, true);
            // regular message for after move
            move.Format(this, ChatMovedForBalance, false, false);
            move.Format(this, YellMovedForBalance, true, false);
            move.Fast = true;
            String why = "because difference is " + diff;
            log = "^4^bFAST BALANCE^n^0 moving ^b" + player.FullName + "^n from " + move.SourceName + " team to " + move.DestinationName + " team " + why;
            log = (EnableLoggingOnlyMode) ? "^9(SIMULATING)^0 " + log : log;
            DebugWrite(log, 3);

            DebugWrite("^9" + move, 8);

            player.LastMoveFrom = player.Team;
            fLastFastMoveTimestamp = DateTime.Now;

            KillAndMoveAsync(move);

            /*
            if (EnableLoggingOnlyMode) {
            // Simulate completion of move
            OnPlayerTeamChange(name, toTeam, 0);
            OnPlayerMovedByAdmin(name, toTeam, 0, false); // simulate reverse order
            }
            */
        }
MULTIbalancer