void OnAdvancingToNextLevel() { LastMapVoters.Clear(); var levelLookup = new Dictionary <string, DistanceLevel>(); var validVotes = new Dictionary <string, int>(); foreach (var vote in PlayerVotes) { var distancePlayer = Server.GetDistancePlayer(vote.Key); if (distancePlayer == null) { if (!LeftAt.ContainsKey(vote.Key) || DistanceServerMain.UnixTime - LeftAt[vote.Key] > 5 * 60) { PlayerVotes.Remove(vote.Key); PlayerVoteTimes.Remove(vote.Key); LeftAt.Remove(vote.Key); } } else { var isBadVoter = IsBadVoter(distancePlayer, DistanceServerMain.UnixTime); var isLateVote = PlayerVoteTimes[vote.Key] > DistanceServerMain.UnixTime - VoteNotSafetyTime; if (isBadVoter && isLateVote) { Server.SayLocalChat(distancePlayer.UnityPlayer, DistanceChat.Server("VoteCommands:LateVote", "Your vote has been skipped this round because you voted late!\nYour vote will apply on the next round.")); } else { int count = 0; validVotes.TryGetValue(vote.Value.RelativeLevelPath, out count); validVotes[vote.Value.RelativeLevelPath] = count + 1; if (!levelLookup.ContainsKey(vote.Value.RelativeLevelPath)) { levelLookup[vote.Value.RelativeLevelPath] = vote.Value; } } } } foreach (var pair in RecentMaps.ToArray()) { if (Server.CurrentLevelId > pair.Value) { RecentMaps.Remove(pair.Key); } } var votesSum = 0; foreach (var vote in validVotes.ToArray()) { var data = new FilterLevelRealtimeEventData(levelLookup[vote.Key]); OnFilterLevelRealtime.Fire(data); if (data.HardBlocklist || (data.SoftBlocklist && vote.Value < NeededVotesToOverrideSoftBlocklist)) { validVotes.Remove(vote.Key); } else { var value = vote.Value; if (AgainstVotes.ContainsKey(vote.Key)) { var count = 0; foreach (var guid in AgainstVotes[vote.Key]) { if (Server.GetDistancePlayer(guid) != null) { count++; value--; } } } if (value <= 0) { validVotes.Remove(vote.Key); } else { validVotes[vote.Key] = value; votesSum += value; } } } foreach (var pair in LeftAt.ToArray()) { if (DistanceServerMain.UnixTime - pair.Value > 5 * 60) { LeftAt.Remove(pair.Key); foreach (var votePair in AgainstVotes.ToArray()) { votePair.Value.Remove(pair.Key); if (votePair.Value.Count == 0) { AgainstVotes.Remove(votePair.Key); } } } } if (validVotes.Count == 0) { return; } var choiceInt = new Random().Next(votesSum); var choiceSum = 0; DistanceLevel level = null; foreach (var pair in validVotes) { choiceSum += pair.Value; if (choiceInt < choiceSum) { level = levelLookup[pair.Key]; break; } } if (level == null) { return; } autoServer.SetNextLevel(level); var voteCount = 0; string firstPlayer = null; foreach (var vote in PlayerVotes.ToArray()) { var distancePlayer = Server.GetDistancePlayer(vote.Key); if (vote.Value.RelativeLevelPath == level.RelativeLevelPath && distancePlayer != null) { voteCount++; PlayerVotes.Remove(vote.Key); PlayerVoteTimes.Remove(vote.Key); LastMapVoters.Add(new MapVoterInfo(distancePlayer)); if (firstPlayer == null) { firstPlayer = vote.Key; } } } var nextLevelId = Server.CurrentLevelId + 1; EventCleaner conns = new EventCleaner(); conns.Add( Server.OnModeStartedEvent.Connect(() => { var chat = DistanceChat.Server("VoteCommands:ChosenLevel", $"Chosen level is [00FF00]{level.Name}[-], voted for by {Server.GetDistancePlayer(firstPlayer).Name}" + (voteCount > 1 ? $" and {voteCount - 1} others" : "")); Server.SayChat(chat); conns.Clean(); }), Server.OnLevelStartInitiatedEvent.Connect(() => { if (Server.CurrentLevelId != nextLevelId) { conns.Clean(); } }) ); }
//Remove Listener Methods private void AddToEventCleaner() { EventCleaner eventCleaner = FindObjectOfType <EventCleaner>(); eventCleaner.AddListenerToClear(this); }