public void OnNeedToSyncLateClientToGameMode(DistancePlayer player) { DistanceServerMain.GetEvent <Events.ServerToClient.SyncMode>().Fire( player.UnityPlayer, new Distance::Events.GameMode.SyncMode.Data(Plugin.ServerStage == BasicAutoServer.Stage.AllFinished) ); }
public void OnPlayerConnected(NetworkPlayer player) { var distancePlayer = new DistancePlayer(this, player.guid); DistancePlayers[player.guid] = distancePlayer; foreach (var existingPlayer in ValidPlayers) { DistanceServerMain.GetEvent <Events.ServerToClient.AddClient>().Fire( player, existingPlayer.GetAddClientData(false) ); } foreach (var line in ChatLog) { distancePlayer.ChatLog.Add(line); } distancePlayer.ResendChat(); SendLevelInfo(player); DistanceServerMain.GetEvent <Events.ServerToClient.Request>().Fire( player, new Distance::Events.ServerToClient.Request.Data(Distance::ServerRequest.SubmitClientInfo) ); distancePlayer.JoinedAt = DistanceServerMain.UnixTime; OnPlayerConnectedEvent.Fire(distancePlayer); }
public void TagPlayer(DistancePlayer player) { if (TaggedPlayer == player) { Log.Debug("Player same"); return; } if (player == null) { Log.Debug("Player null"); TaggedPlayer = null; return; } var lastTagData = TaggedPlayer?.GetExternalData <ReverseTagData>(); double lastSecondsTagged = lastTagData == null ? 0.0 : lastTagData.SecondsTagged; TimeOfLastTag = Plugin.Server.ModeTime; var networkTagData = new Distance::Events.ReverseTag.TaggedPlayer.Data(player.Index, lastSecondsTagged, TimeOfLastTag); DistanceServerMain.GetEvent <Events.ServerToClient.TaggedPlayer>().Fire(UnityEngine.RPCMode.Others, networkTagData); TaggedPlayer = player; LockTagBubbleFor(5); }
public void ClearBadVoterBelow(DistancePlayer player, double at) { var until = GetBadVoterUntil(player); if (until != 0.0) { foreach (var pair in BadVoterUnityGuids) { if (pair.Value == until) { BadVoterUnityGuids.Remove(pair.Key); break; } } foreach (var pair in BadVoterNames) { if (pair.Value == until) { BadVoterNames.Remove(pair.Key); break; } } foreach (var pair in BadVoterIps) { if (pair.Value == until) { BadVoterIps.Remove(pair.Key); break; } } } }
public bool IsPlayerInMode(DistancePlayer player) { return(player.Valid && !player.IsLoading() && player.LevelId == Plugin.Server.CurrentLevelId && player.Car != null && !player.Car.Finished && player.GetExternalData <ReverseTagData>() != null); }
public bool UpdateLevelCompatabilityStatus(DistancePlayer player) { if (player.LevelCompatibilityInfo.LevelCompatibilityId != CurrentLevelId || player.LevelCompatability == Distance::LevelCompatabilityStatus.Unverified) { RequestLevelCompatibilityInfo(player.UnityPlayer); return(false); } return(true); }
public double GetBadVoterUntil(DistancePlayer player) { double until = 0.0; BadVoterNames.TryGetValue(player.Name, out until); BadVoterUnityGuids.TryGetValue(player.UnityPlayerGuid, out until); BadVoterIps.TryGetValue(player.UnityPlayer.externalIP, out until); return(until); }
public void SayLocalChat(NetworkPlayer player, DistanceChat chat) { DistancePlayer distancePlayer = null; DistancePlayers.TryGetValue(player.guid, out distancePlayer); if (distancePlayer != null) { distancePlayer.SayLocalChat(chat); } }
System.Collections.IEnumerator RestartPlayerAfter(DistancePlayer player, float time) { player.RestartTime = DistanceServerMain.UnixTime; autoServer.SetStartingPlayer(player.UnityPlayerGuid, false); player.Car.BroadcastDNF(); yield return(new UnityEngine.WaitForSeconds(time)); player.Car = null; // if the car stays in the game, the player will get stuck on the loading screen! Server.SendPlayerToLevel(player.UnityPlayer); }
public System.Collections.IEnumerator GiveTagBubbleSoon(DistancePlayer fromPlayer, DistancePlayer player) { yield return(new UnityEngine.WaitForSeconds(1)); if (IsPlayerInMode(player) && TaggedPlayer == fromPlayer) { fromPlayer.GetExternalData <ReverseTagData>().SecondsTagged = 0.0; TagPlayer(player); } fromPlayer.SayLocalChat(DistanceChat.Server("ReverseTag:SinglePlayerTransition", "Transitioning out of single-player: your timer has been reset and your tag bubble taken!")); }
public DistanceCar(DistancePlayer player, Distance::PlayerInitializeData data) { Player = player; PlayerViewId = data.playerViewID_; CarViewId1 = data.carViewID0_; CarViewId2 = data.carViewID1_; CarColors = data.carColors_; PlayerName = data.playerName_; CarName = data.carName_; var index = 0; foreach (var evt in InstancedEvents) { if (evt != null) { var instancedEvt = (InstancedNetworkEventNonGeneric)evt; instancedEvt.eventIndex = index; instancedEvt.instance = this; instancedEvt.NonGenericWith((InstancedNetworkEventNonGeneric)DistanceServerMain.InstancedEvents[index]); } index++; } GetEvent <Events.Instanced.CarRespawn>().Connect(evtData => { Transform.position = evtData.position_; Transform.rotation = evtData.rotation_; RigidbodyStateTransceiver.Clear(); }); GetEvent <Events.Instanced.PreTeleport>().Connect(evtData => { RigidbodyStateTransceiver.Clear(); }); GetEvent <Events.Instanced.WingsStateChange>().Connect(evtData => { WingsOpen = evtData.open_; }); GetEvent <Events.Instanced.Death>().Connect(evtData => { Alive = false; }); GetEvent <Events.Instanced.CarRespawn>().Connect(evtData => { Alive = true; }); GetEvent <Events.Instanced.Finished>().Connect(evtData => { Finished = true; FinishType = evtData.finishType_; FinishData = evtData.finishData_; }); }
public void OnNeedToSyncLateClientToGameMode(DistancePlayer player) { DistanceServerMain.GetEvent <Events.ServerToClient.SyncMode>().Fire( player.UnityPlayer, new Distance::Events.GameMode.SyncMode.Data(Finished) ); if (TaggedPlayer != null) { DistanceServerMain.GetEvent <Events.ServerToClient.TaggedPlayer>().Fire( player.UnityPlayer, new Distance::Events.ReverseTag.TaggedPlayer.Data(TaggedPlayer.Index, 0.0, TimeOfLastTag) ); } }
public List <DistancePlayer> GetLastPlacePlayers(DistancePlayer exclude = null) { var players = GetModePlayers(); players.RemoveAll(player => player == exclude); players.Sort((a, b) => a.GetExternalData <ReverseTagData>().MillisTagged - b.GetExternalData <ReverseTagData>().MillisTagged); var minMillisTagged = -1; return(players.TakeWhile((player) => { if (minMillisTagged == -1) { minMillisTagged = player.GetExternalData <ReverseTagData>().MillisTagged; } return player.GetExternalData <ReverseTagData>().MillisTagged == minMillisTagged; }).ToList()); }
internal RequestInfo(HttpListenerContext context, string body, Entry plugin) { Context = context; Body = body; Plugin = plugin; IsPrivateMode = TestPrivateMode(); SessionId = GetSessionId(); if (SessionId == null) { SessionId = Guid.NewGuid().ToString(); Context.Response.Cookies.Add(new Cookie("DistanceSession", SessionId)); } Plugin.Expiry[SessionId] = DistanceServerMain.UnixTime + 10 * 60; UnityPlayerGUID = GetUnityPlayerGUID(); if (UnityPlayerGUID != null) { DistancePlayer = Plugin.Server.GetDistancePlayer(UnityPlayerGUID); } }
public System.Collections.IEnumerator SearchForLevels(DistancePlayer searcher, string searchText, bool isVote, bool isAgainst) { var autoServer = Manager.GetPlugin <BasicAutoServer.BasicAutoServer>(); var byMatch = Regex.Match(searchText, @"by (.*)$"); string onlyBy = null; if (byMatch.Success) { searchText = Regex.Replace(searchText, @"\s*by (.*)$", ""); onlyBy = byMatch.Groups[1].ToString(); } var searches = new List <WorkshopSearch.DistanceSearchRetriever>(); if (RequiredTags.Count == 0) { searches.Add(new WorkshopSearch.DistanceSearchRetriever(new WorkshopSearch.DistanceSearchParameters() { Search = new WorkshopSearch.WorkshopSearchParameters() { AppId = WorkshopSearch.Workshop.DistanceAppId, SearchText = searchText, SearchType = WorkshopSearch.WorkshopSearchParameters.SearchTypeType.GameFiles, Sort = WorkshopSearch.WorkshopSearchParameters.SortType.Relevance, Days = -1, NumPerPage = 30, Page = 1, RequiredTags = new string[] { }, }, GameMode = autoServer.GameMode, MaxSearch = 5 * 30, MaxResults = 3, DistanceLevelFilter = (levels) => { if (onlyBy != null) { levels.RemoveAll(level => { return(!level.WorkshopItemResult.AuthorName.ToLower().Contains(onlyBy.ToLower())); }); } return(autoServer.FilterWorkshopLevels(levels)); } })); } else { foreach (var tag in RequiredTags) { searches.Add(new WorkshopSearch.DistanceSearchRetriever(new WorkshopSearch.DistanceSearchParameters() { Search = new WorkshopSearch.WorkshopSearchParameters() { AppId = WorkshopSearch.Workshop.DistanceAppId, SearchText = searchText, SearchType = WorkshopSearch.WorkshopSearchParameters.SearchTypeType.GameFiles, Sort = WorkshopSearch.WorkshopSearchParameters.SortType.Relevance, Days = -1, NumPerPage = 30, Page = 1, RequiredTags = new string[] { tag }, }, GameMode = autoServer.GameMode, MaxSearch = 5 * 30, MaxResults = 3, DistanceLevelFilter = (levels) => { if (onlyBy != null) { levels.RemoveAll(level => { return(!level.WorkshopItemResult.AuthorName.ToLower().Contains(onlyBy.ToLower())); }); } return(autoServer.FilterWorkshopLevels(levels)); } })); } } var items = new List <WorkshopSearch.DistanceSearchResultItem>(); foreach (var search in searches) { yield return(search.TaskCoroutine); if (search.HasError) { Server.SayLocalChat(searcher.UnityPlayer, DistanceChat.Server("VoteCommands:Feedback:SearchError", $"Error when searching for \"{searchText}\"")); Log.Error($"Error when searching for \"{searchText}\": {search.Error}"); yield break; } items.AddRange(search.Results); } if (items.Count == 0) { Server.SayLocalChat(searcher.UnityPlayer, DistanceChat.Server("VoteCommands:Feedback:SearchResult", $"No levels found for \"{searchText}\"" + (onlyBy != null ? $" by \"{onlyBy}\"" : ""))); yield break; } if (!isVote) { var result = $"Levels for \"{searchText}\":"; for (int i = 0; i < Math.Min(3, items.Count); i++) { var item = items[i].WorkshopItemResult; result += $"\n[00FF00]{item.ItemName}[-] by {item.AuthorName}" + (item.Rating == -1 ? "" : $" {item.Rating}/5"); } Server.SayLocalChat(searcher.UnityPlayer, DistanceChat.Server("VoteCommands:Feedback:SearchResult", result)); yield break; } else { var result = items[0].DistanceLevelResult; if (!isAgainst) { var data = new FilterLevelRealtimeEventData(result); OnFilterLevelRealtime.Fire(data); if (data.HardBlocklist) { Server.SayChat(DistanceChat.Server("VoteCommands:Feedback:VoteHardBlocked", $"The level [00FF00]{result.Name}[-] by {items[0].WorkshopItemResult.AuthorName} is blocked because {data.Reason}.")); yield break; } PlayerVotes[searcher.UnityPlayerGuid] = result; PlayerVoteTimes[searcher.UnityPlayerGuid] = DistanceServerMain.UnixTime; Server.SayChat(DistanceChat.Server("VoteCommands:Feedback:VoteSuccess", $"Set {searcher.Name}'s vote to [00FF00]{result.Name}[-] by {items[0].WorkshopItemResult.AuthorName}")); if (data.SoftBlocklist) { int count = PlayerVotes.Sum(pair => { if (pair.Value.RelativeLevelPath != result.RelativeLevelPath || Server.GetDistancePlayer(pair.Key) == null) { return(0); } return(1); }); int sub = 0; if (AgainstVotes.ContainsKey(result.RelativeLevelPath)) { sub = AgainstVotes[result.RelativeLevelPath].Sum(playerGuid => Server.GetDistancePlayer(playerGuid) != null ? 1 : 0); } count = count - sub; int needed = NeededVotesToExtendLevel - count; if (needed > 0) { Server.SayChat(DistanceChat.Server("VoteCommands:Feedback:VoteSoftBlocked", $"The level [00FF00]{result.Name}[-] is soft-blocked and needs {needed} more votes to be played because {data.Reason}.")); } else { Server.SayChat(DistanceChat.Server("VoteCommands:Feedback:VoteSuccessSoftBlock", $"The level [00FF00]{result.Name}[-] is soft-blocked but has met its required vote count and can now be played.")); } } } else { var key = result.RelativeLevelPath; if (!AgainstVotes.ContainsKey(key)) { AgainstVotes[key] = new HashSet <string>(); } if (AgainstVotes[key].Contains(searcher.UnityPlayerGuid)) { AgainstVotes[key].Remove(searcher.UnityPlayerGuid); if (AgainstVotes[key].Count == 0) { AgainstVotes.Remove(key); } Server.SayChat(DistanceChat.Server("VoteCommands:Feedback:AgainstVoteRemoved", $"Cleared {searcher.Name}'s vote against [00FF00]{result.Name}[-] by {items[0].WorkshopItemResult.AuthorName}")); } else { AgainstVotes[key].Add(searcher.UnityPlayerGuid); Server.SayChat(DistanceChat.Server("VoteCommands:Feedback:AgainstVoteAdded", $"Set {searcher.Name}'s vote against [00FF00]{result.Name}[-] by {items[0].WorkshopItemResult.AuthorName}")); } } yield break; } }
public bool IsBadVoter(DistancePlayer player, double at) { var until = GetBadVoterUntil(player); return(until != 0.0 && at < until); }
public MapVoterInfo(DistancePlayer player) { Name = player.Name; UnityGuid = player.UnityPlayerGuid; Ip = player.UnityPlayer.externalIP; }
public void SetBadVoterUntil(DistancePlayer player, double at) { BadVoterNames[player.Name] = at; BadVoterUnityGuids[player.UnityPlayerGuid] = at; BadVoterIps[player.UnityPlayer.externalIP] = at; }
public void OnPlayerConnected(DistancePlayer player) { player.AddExternalData(new ReverseTagData()); }
public void Update() { if (Finished) { return; } if (Plugin.ServerStage != BasicAutoServer.Stage.Started) { return; } var playersInMode = GetModePlayers(); if (playersInMode.Count <= 1) { IsInSinglePlayerMode = true; MaxModeTime += UnityEngine.Time.deltaTime; } else if (IsInSinglePlayerMode) { IsInSinglePlayerMode = false; // When transitioning out of single-player mode, give the bubble to the new player to reset the timer: if (TaggedPlayer != null) { var nonTagged = playersInMode.Find((player) => TaggedPlayer != player); if (nonTagged != null) { TaggedPlayer.GetExternalData <ReverseTagData>().SecondsTagged = 0.0; DistanceServerMainStarter.Instance.StartCoroutine(GiveTagBubbleSoon(TaggedPlayer, nonTagged)); } } } if (TaggedPlayer != null && !IsPlayerInMode(TaggedPlayer)) { TagRandomLastPlacePlayer(); if (!IsPlayerInMode(TaggedPlayer)) { TagPlayer(null); } } if (TaggedPlayer != null && !IsInSinglePlayerMode) { TaggedPlayer.GetExternalData <ReverseTagData>().AddSecondsTagged(UnityEngine.Time.deltaTime, WinTime); } var leader = GetFirstPlacePlayer(); if (leader != Leader) { if (leader != null) { var colorHex = Distance::ColorEx.ColorToHexNGUI(Distance::ColorEx.PlayerRainbowColor(leader.Index)); var nameColored = $"[{colorHex}]{leader.Name}[-]"; var chat = DistanceChat.Server("Vanilla:TakenTheLead", $"{nameColored} has taken the lead!"); chat.ChatType = DistanceChat.ChatTypeEnum.ServerVanilla; Plugin.Server.SayChat(chat); } Leader = leader; } var leaderSecondsTagged = Leader == null ? 0.0 : Leader.GetExternalData <ReverseTagData>().SecondsTagged; if (leaderSecondsTagged >= WinTime || Plugin.Server.ModeTime >= MaxModeTime) { Finished = true; if (Leader != null) { var networkFinishedData = new Distance::Events.ReverseTag.Finished.Data(Leader.Index, leaderSecondsTagged); DistanceServerMain.GetEvent <Events.ServerToClient.ReverseTagFinished>().Fire(UnityEngine.RPCMode.Others, networkFinishedData); } Log.Debug($"Advancing level because win condition met: {leaderSecondsTagged} >= {WinTime} || {Plugin.Server.ModeTime} > {MaxModeTime}"); Plugin.AdvanceLevel(); } if (Finished) { return; } AdvanceLevelIfOnlyFinishedPlayers(); var secondsLeft = Math.Max(0.0, Math.Min(WinTime - leaderSecondsTagged, MaxModeTime - Plugin.Server.ModeTime)); if (secondsLeft <= 30 && !HasShown30SecondWarning) { HasShown30SecondWarning = true; var colorHex = Distance::ColorEx.ColorToHexNGUI(Distance::Colors.orangeRed); var chat = DistanceChat.Server("Vanilla:TimeWarning", $"[{colorHex}]30 seconds left![-]"); chat.ChatType = DistanceChat.ChatTypeEnum.ServerVanilla; Plugin.Server.SayChat(chat); } else if (secondsLeft <= 10 && !HasShown10SecondWarning) { HasShown10SecondWarning = true; var colorHex = Distance::ColorEx.ColorToHexNGUI(Distance::Colors.orangeRed); var chat = DistanceChat.Server("Vanilla:TimeWarning", $"[{colorHex}]10 seconds left![-]"); chat.ChatType = DistanceChat.ChatTypeEnum.ServerVanilla; Plugin.Server.SayChat(chat); } }