Example #1
0
 private void ScheduleListPlayers(double delay)
 {
     DelayedRequest r = new DelayedRequest(delay, fListPlayersTimestamp);
     DebugWrite("^9Scheduling listPlayers no sooner than " + r.MaxDelay  + " seconds from " + r.LastUpdate.ToString("HH:mm:ss"), 7);
     lock (fListPlayersQ) {
     fListPlayersQ.Enqueue(r);
     Monitor.Pulse(fListPlayersQ);
     }
 }
Example #2
0
        private void Reset()
        {
            ResetRound();

            lock (fPriorityFetchQ) {
            fPriorityFetchQ.Clear();
            Monitor.Pulse(fPriorityFetchQ);
            }

            lock (fMoveQ) {
            fMoveQ.Clear();
            Monitor.Pulse(fMoveQ);
            }

            lock (fListPlayersQ) {
            fListPlayersQ.Clear();
            Monitor.Pulse(fListPlayersQ);
            }

            lock (fAllPlayers) {
            fAllPlayers.Clear();
            }

            lock (fMoving) {
            fMoving.Clear();
            }

            lock (fMoveStash) {
            fMoveStash.Clear();
            }

            lock (fExtrasLock) {
            fExtraNames.Clear();
            fDebugScramblerSuspects.Clear();
            }

            fReassigned.Clear();
            fPendingTeamChange.Clear();
            fUnassigned.Clear();

            /*
            fKnownPlayers is not cleared right away, since we want to retain stats from previous plugin sessions.
            It will be garbage collected after MODEL_MINUTES.
            */

            fServerInfo = null; // release Procon reference
            fListPlayersTimestamp = DateTime.MinValue;
            fRefreshCommand = false;
            fServerUptime = 0;
            fServerCrashed  = false;
            fFinalStatus = null;
            fMaxTickets = -1;
            fBalanceIsActive = false;
            fIsFullRound = false;
            fLastMsg = null;
            fRoundsEnabled = 0;
            fGrandTotalQuits = 0;
            fGrandRageQuits = 0;
            fWhileScrambling = false;
            fUpdateTicketsRequest = null;
            fTotalRoundEndingRounds = 0;
            fTotalRoundEndingSeconds = 0;

            fDebugScramblerBefore[0].Clear();
            fDebugScramblerBefore[1].Clear();
            fDebugScramblerAfter[0].Clear();
            fDebugScramblerAfter[1].Clear();
            fDebugScramblerStartRound[0].Clear();
            fDebugScramblerStartRound[1].Clear();
        }
Example #3
0
        /* Constructor */
        public MULTIbalancer()
        {
            /* Private members */
            fIsEnabled = false;
            fFinalizerActive = false;
            fPluginState = PluginState.Disabled;
            fGameState = GameState.Unknown;
            fServerInfo = null;
            fRefreshCommand = false;
            fServerUptime = 0;
            fServerCrashed = false;
            fDebugScramblerBefore = new List<PlayerModel>[2]{new List<PlayerModel>(), new List<PlayerModel>()};
            fDebugScramblerAfter = new List<PlayerModel>[2]{new List<PlayerModel>(), new List<PlayerModel>()};
            fDebugScramblerStartRound = new List<PlayerModel>[2]{new List<PlayerModel>(), new List<PlayerModel>()};

            fBalancedRound = 0;
            fUnstackedRound = 0;
            fUnswitchedRound = 0;
            fExcludedRound = 0;
            fExemptRound = 0;
            fFailedRound = 0;
            fTotalRound = 0;
            fBalanceIsActive = false;
            fRoundsEnabled = 0;
            fGrandTotalQuits = 0;
            fGrandRageQuits = 0;
            fTotalQuits = 0;
            fRageQuits = 0;

            fMoveThread = null;
            fFetchThread = null;
            fListPlayersThread = null;
            fScramblerThread = null;
            fTimerThread = null;

            fModeToSimple = new Dictionary<String,String>();

            fEasyTypeDict = new Dictionary<int, Type>();
            fEasyTypeDict.Add(0, typeof(int));
            fEasyTypeDict.Add(1, typeof(Int16));
            fEasyTypeDict.Add(2, typeof(Int32));
            fEasyTypeDict.Add(3, typeof(Int64));
            fEasyTypeDict.Add(4, typeof(float));
            fEasyTypeDict.Add(5, typeof(long));
            fEasyTypeDict.Add(6, typeof(String));
            fEasyTypeDict.Add(7, typeof(string));
            fEasyTypeDict.Add(8, typeof(double));

            fBoolDict = new Dictionary<int, Type>();
            fBoolDict.Add(0, typeof(Boolean));
            fBoolDict.Add(1, typeof(bool));

            fListStrDict = new Dictionary<int, Type>();
            fListStrDict.Add(0, typeof(String[]));

            fPerMode = new Dictionary<String,PerModeSettings>();

            fAllPlayers = new List<String>();
            fKnownPlayers = new Dictionary<String, PlayerModel>();
            fTeam1 = new List<PlayerModel>();
            fTeam2 = new List<PlayerModel>();
            fTeam3 = new List<PlayerModel>();
            fTeam4 = new List<PlayerModel>();
            fUnassigned = new List<String>();
            fRoundStartTimestamp = DateTime.MinValue;
            fRoundOverTimestamp = DateTime.MinValue;
            fListPlayersTimestamp = DateTime.MinValue;
            fFullUnstackSwapTimestamp = DateTime.MinValue;
            fLastValidationTimestamp = DateTime.MinValue;
            fListPlayersQ = new Queue<DelayedRequest>();

            fPendingTeamChange = new Dictionary<String,int>();
            fMoving = new Dictionary<String, MoveInfo>();
            fMoveQ = new Queue<MoveInfo>();
            fReassigned = new List<String>();
            fReservedSlots = new List<String>();
            fTickets = new int[5]{0,0,0,0,0};
            fFriendlyMaps = new Dictionary<String,String>();
            fFriendlyModes = new Dictionary<String,String>();
            fMaxTickets = -1;
            fRushMaxTickets = -1;
            fLastBalancedTimestamp = DateTime.MinValue;
            fEnabledTimestamp = DateTime.MinValue;
            fFinalStatus = null;
            fIsFullRound = false;
            fUnstackState = UnstackState.Off;
            fLastMsg = null;
            fRushStage = 0;
            fRushPrevAttackerTickets = 0;
            fRushAttackerStageLoss = 0;
            fRushAttackerStageSamples = 0;
            fMoveStash = new List<MoveInfo>();
            fLastVersionCheckTimestamp = DateTime.MinValue;
            fTimeOutOfJoint = 0;
            fUnstackGroupCount = 0;
            fPriorityFetchQ = new PriorityQueue(this);
            fIsCacheEnabled = false;
            fScramblerLock = new DelayedRequest();
            fWinner = 0;
            fUpdateThreadLock = new DelayedRequest();
            fLastServerInfoTimestamp = DateTime.Now;
            fStageInProgress = false;
            fHost = String.Empty;
            fPort = String.Empty;
            fRushMap3Stages = new List<String>(new String[6]{"MP_007", "XP4_Quake", "XP5_002", "MP_012", "XP4_Rubble", "MP_Damage"});
            fRushMap5Stages = new List<String>(new String[6]{"MP_013", "XP3_Valley", "MP_017", "XP5_001", "MP_Prison", "MP_Siege"});
            fGroupAssignments = new int[5]{0,0,0,0,0};
            fDispersalGroups = new List<String>[5]{null, new List<String>(), new List<String>(), new List<String>(), new List<String>()};
            fNeedPlayerListUpdate = false;
            fFriends = new Dictionary<int, List<String>>();
            fAllFriends = new List<String>();
            fWhileScrambling = false;
            fExtrasLock = new DelayedRequest();
            fExtraNames = new List<String>();
            fGotLogin = false;
            fDebugScramblerSuspects = new Dictionary<String,String>();
            fTimerRequestList = new List<DelayedRequest>();
            fAverageTicketLoss = new Queue<double>[3]{null, new Queue<double>(), new Queue<double>()};
            fTicketLossHistogram = new Histogram();

            /* Settings */

            /* ===== SECTION 0 - Presets ===== */

            SettingsVersion = 1;
            Preset = PresetItems.Standard;
            EnableUnstacking = false;
            EnableSettingsWizard = false;
            WhichMode = "Conquest Large";
            MetroIsInMapRotation = false;
            MaximumPlayersForMode = 64;
            LowestMaximumTicketsForMode = 300;
            HighestMaximumTicketsForMode = 400;
            PreferredStyleOfBalancing = PresetItems.Standard;
            ApplySettingsChanges = false;

            /* ===== SECTION 1 - Settings ===== */

            DebugLevel = 2;
            MaximumServerSize = 64;
            EnableBattlelogRequests = true;
            MaximumRequestRate = 10; // in 20 seconds
            WaitTimeout = 30; // seconds
            WhichBattlelogStats = BattlelogStats.ClanTagOnly;
            MaxTeamSwitchesByStrongPlayers = 1;
            MaxTeamSwitchesByWeakPlayers = 2;
            UnlimitedTeamSwitchingDuringFirstMinutesOfRound = 5.0;
            Enable2SlotReserve = false;
            EnablerecruitCommand = false;
            EnableWhitelistingOfReservedSlotsList = true;
            Whitelist = new String[] {DEFAULT_LIST_ITEM};
            fSettingWhitelist = new List<String>(Whitelist);
            DisperseEvenlyList = new String[] {DEFAULT_LIST_ITEM};
            fSettingDisperseEvenlyList = new List<String>(DisperseEvenlyList);
            FriendsList = new String[] {DEFAULT_LIST_ITEM};
            fSettingFriendsList = new List<String>();
            SecondsUntilAdaptiveSpeedBecomesFast = 3*60; // 3 minutes default
            EnableInGameCommands = true;

            /* ===== SECTION 2 - Exclusions ===== */

            OnWhitelist = true;
            OnFriendsList = false;
            ApplyFriendsListToTeam = false;
            TopScorers = true;
            SameClanTagsInSquad = true;
            SameClanTagsInTeam = false;
            SameClanTagsForRankDispersal = false;
            LenientRankDispersal = false;
            MinutesAfterJoining = 5;
            MinutesAfterBeingMoved = 90; // 1.5 hours
            JoinedEarlyPhase = true;
            JoinedMidPhase = true;
            JoinedLatePhase = false;

            /* ===== SECTION 3 - Round Phase & Population Settings ===== */

            EarlyPhaseTicketPercentageToUnstack = new double[3]         {  0,120,120};
            MidPhaseTicketPercentageToUnstack = new double[3]           {  0,120,120};
            LatePhaseTicketPercentageToUnstack = new double[3]          {  0,  0,  0};

            EnableTicketLossRateLogging = false;

            SpellingOfSpeedNamesReminder = Speed.Click_Here_For_Speed_Names;

            EarlyPhaseBalanceSpeed = new Speed[3]           {     Speed.Fast, Speed.Adaptive, Speed.Adaptive};
            MidPhaseBalanceSpeed = new Speed[3]             {     Speed.Fast, Speed.Adaptive, Speed.Adaptive};
            LatePhaseBalanceSpeed = new Speed[3]            {     Speed.Stop,     Speed.Stop,     Speed.Stop};

            /* ===== SECTION 4 - Scrambler ===== */

            OnlyOnNewMaps = true; // false means scramble every round
            OnlyOnFinalTicketPercentage = 120; // 0 means scramble regardless of final score
            ScrambleBy = DefineStrong.RoundScore;
            KeepSquadsTogether = true;
            KeepClanTagsInSameTeam = true;
            KeepFriendsInSameTeam = false;
            DivideBy = DivideByChoices.None;
            ClanTagToDivideBy = String.Empty;
            DelaySeconds = 50;

            /* ===== SECTION 5 - Messages ===== */

            QuietMode = false; // false: chat is global, true: chat is private. Yells are always private
            YellDurationSeconds = 10;
            BadBecauseMovedByBalancer = "autobalance moved you to the %toTeam% team";
            BadBecauseWinningTeam = "switching to the winning team is not allowed";
            BadBecauseBiggestTeam = "switching to the biggest team is not allowed";
            BadBecauseRank = "this server splits Colonel 100's between teams";
            BadBecauseDispersalList = "you're on the list of players to split between teams";
            ChatMovedForBalance = "*** MOVED %name% for balance ...";
            YellMovedForBalance = "Moved %name% for balance ...";
            ChatMovedToUnstack = "*** MOVED %name% to unstack teams ...";
            YellMovedToUnstack = "Moved %name% to unstack teams ...";
            ChatDetectedBadTeamSwitch = "%name%, you can't switch to team %fromTeam%: %reason%, sending you back ...";
            YellDetectedBadTeamSwitch = "You can't switch to the %fromTeam% team: %reason%, sending you back!";
            ChatDetectedGoodTeamSwitch = "%name%, thanks for helping out the %toTeam% team!";
            YellDetectedGoodTeamSwitch = "Thanks for helping out the %toTeam% team!";
            ChatAfterUnswitching = "%name%, please stay on the %toTeam% team for the rest of this round";
            YellAfterUnswitching = "Please stay on the %toTeam% team for the rest of this round";

            /* ===== SECTION 6 - Unswitcher ===== */

            EnableImmediateUnswitch = true;
            ForbidSwitchingAfterAutobalance = UnswitchChoice.Always;
            ForbidSwitchingToWinningTeam = UnswitchChoice.Always;
            ForbidSwitchingToBiggestTeam = UnswitchChoice.Always;
            ForbidSwitchingAfterDispersal = UnswitchChoice.Always;

            /* ===== SECTION 7 - TBD ===== */

            /* ===== SECTION 8 - Per-Mode Settings ===== */

            /* ===== SECTION 9 - Debug Settings ===== */

            ShowInLog = INVALID_NAME_TAG_GUID;
            ShowCommandInLog = String.Empty;
            LogChat = true;
            EnableLoggingOnlyMode = false;
            EnableExternalLogging = false;
            ExternalLogSuffix = "_mb.log";
        }
Example #4
0
 private DelayedRequest AddTimedRequest(String name, double maxDelay, Action<DateTime> request)
 {
     DelayedRequest r = null;
     lock (fTimerRequestList) {
     foreach (DelayedRequest old in fTimerRequestList) {
     if (!String.IsNullOrEmpty(old.Name) && !String.IsNullOrEmpty(name) && old.Name == name) {
         ConsoleDebug("ASSERT AddTimedRequest: request with name ^b" + name + "^n already exists, skipping!");
         return null;
     }
     }
     r = new DelayedRequest();
     r.Name = name;
     r.MaxDelay = maxDelay;
     r.LastUpdate = DateTime.MinValue;
     r.Request = request;
     ConsoleDebug("Added: " + name);
     fTimerRequestList.Add(r);
     }
     return r;
 }
Example #5
0
 private void SetupUpdateTicketsRequest()
 {
     if (fUpdateTicketsRequest != null) return;
     fUpdateTicketsRequest = AddTimedRequest("Update serverInfo every 5 seconds", 5.0, delegate(DateTime now) {
     try {
     if (fGameState == GameState.Playing && TotalPlayerCount >= 4) ServerCommand("serverInfo");
     } catch (Exception) {}
     });
 }