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 static bool CheckCancelled(LocalEvent <Cancellable> evt) { var cancellable = new Cancellable(); evt.Fire(cancellable); return(cancellable.IsCancelled); }
public void OnPlayerDisconnected(NetworkPlayer player) { var distancePlayer = GetDistancePlayer(player); distancePlayer.unityPlayer = player; if (distancePlayer.ReceivedInfo) { ValidPlayers.Remove(distancePlayer); for (int i = distancePlayer.Index; i < ValidPlayers.Count; i++) { ValidPlayers[i].Index = i; } } DistancePlayers.Remove(player.guid); distancePlayer.Car = null; DistanceServerMain.GetEvent <Events.ServerToClient.RemovePlayerFromClientList>().Fire( RPCMode.Others, new Distance::Events.ServerToClient.RemovePlayerFromClientList.Data(player, distancePlayer.Index, Distance::DisconnectionType.Quit) ); if (StartingMode) { AttemptToStartMode(); } distancePlayer.LeftAt = DistanceServerMain.UnixTime; distancePlayer.OnDisconnectedEvent.Fire(); OnPlayerDisconnectedEvent.Fire(distancePlayer); }
public void AddChat(DistanceChat chat) { ChatLog.Add(chat); ChatLogLineCount += chat.Lines.Length; if (ChatLogLineCount - ChatLog[0].Lines.Length >= 64) { ChatLogLineCount = ChatLogLineCount - ChatLog[0].Lines.Length; ChatLog.RemoveAt(0); } OnChatMessageEvent.Fire(chat); }
public void AddChat(DistanceChat chat) { ChatLog.Add(chat); ChatLogLineCount += chat.Lines.Length; if (ChatLogLineCount - ChatLog[0].Lines.Length >= 64) { ChatLogLineCount = ChatLogLineCount - ChatLog[0].Lines.Length; ChatLog.RemoveAt(0); } foreach (var distancePlayer in DistancePlayers.Values) { distancePlayer.AddChat(chat); } OnChatMessageEvent.Fire(chat); }
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(); } }) ); }
public void OnMasterServer(MasterServerEvent evt) { OnMasterServerEvent.Fire(evt); }
public void OnFailedToConnectToMasterServer(NetworkConnectionError error) { OnFailedToConnectToMasterServerEvent.Fire(error); }
/// public void Init() { DistanceServerMain.GetEvent <Events.ClientToServer.SubmitPlayerInfo>().Connect((data, info) => { // ignore data.sender_, it should be sender var player = GetDistancePlayer(info.sender); player.Name = data.playerName_; player.ReceivedInfo = true; player.Index = ValidPlayers.Count; player.ValidatedAt = DistanceServerMain.UnixTime; ValidPlayers.Add(player); player.OnValidatedPreReplicationEvent.Fire(); OnPlayerValidatedPreReplicationEvent.Fire(player); DistanceServerMain.GetEvent <Events.ServerToClient.AddClient>().Fire( RPCMode.Others, player.GetAddClientData(true) ); player.OnValidatedEvent.Fire(); OnPlayerValidatedEvent.Fire(player); }); DistanceServerMain.GetEvent <Events.ClientToServer.CompletedRequest>().Connect((data, info) => { // ignore data.networkPlayer_, it should be sender var distancePlayer = GetDistancePlayer(info.sender); if (data.request_ == Distance::ServerRequest.SubmitClientInfo) // TODO: check if request was actually completed for security { distancePlayer.State = DistancePlayer.PlayerState.Initialized; SendPlayerToCurrentLocation(data.networkPlayer_); } else if (data.request_ == Distance::ServerRequest.LoadLobbyScene) { distancePlayer.Stuck = false; distancePlayer.State = DistancePlayer.PlayerState.LoadedLobbyScene; SendLobbyServerInfo(data.networkPlayer_); SendLevelInfo(data.networkPlayer_); RequestLevelCompatibilityInfo(data.networkPlayer_); RequestSubmitLobbyInfo(data.networkPlayer_); if (!IsInLobby) { distancePlayer.State = DistancePlayer.PlayerState.CantLoadLevelSoInLobby; } } else if (data.request_ == Distance::ServerRequest.SubmitLobbyInfo) { distancePlayer.State = DistancePlayer.PlayerState.SubmittedLobbyInfo; } else if (data.request_ == Distance::ServerRequest.LoadGameModeScene) { distancePlayer.Stuck = false; distancePlayer.State = DistancePlayer.PlayerState.LoadedGameModeScene; if (distancePlayer.LevelId != CurrentLevelId) { SendPlayerToLevel(distancePlayer.UnityPlayer); return; } // fire CreatePlayer for sender for all existing cars (see WelcomeClientToGameMode.Data) foreach (var player in ValidPlayers) { if (player.Car != null) { DistanceServerMain.GetEvent <Events.ServerToClient.CreatePlayer>().Fire( data.networkPlayer_, new Distance::Events.ServerToClient.CreatePlayer.Data(player.Car.GetPlayerInitializeData(), player.Car.GetPlayerLateInitializeData(), player.Index) ); if (!player.Car.Finished && player.Car.Alive) { var gameObject = player.Car.Networker; var transform = gameObject.transform; DistanceServerMain.GetEvent <Events.ServerToClient.CreateExistingCar>().Fire( data.networkPlayer_, new Distance::Events.ServerToClient.CreateExistingCar.Data(transform.position, transform.rotation, player.Car.WingsOpen, player.Index) ); } } } if (HasModeStarted) { // TODO: sync game mode things if already started -- different for every game mode (see SyncLateClientToGameMode.Data and SyncMode.Data) // NOTE: this should be handled entirely by the game mode programming, not by the base server programming OnNeedToSyncLateClientToGameMode.Fire(distancePlayer); if (distancePlayer.Countdown != -1.0) { DistanceServerMain.GetEvent <Events.ServerToClient.FinalCountdownActivate>().Fire( data.networkPlayer_, new Distance::Events.RaceMode.FinalCountdownActivate.Data(distancePlayer.Countdown, (int)(distancePlayer.Countdown - ModeTime)) ); } } RequestSubmitGameModeInfo(data.networkPlayer_); } else if (data.request_ == Distance::ServerRequest.SubmitGameModeInfo) { distancePlayer.State = DistancePlayer.PlayerState.SubmittedGameModeInfo; // If mode has not started, try to start it (check if all players have submitted info/loaded) // If mode has started, set state to StartedMode and fire StartClientLate // (see ServerLogic.OnEventCompletedRequest) if (StartingMode) { AttemptToStartMode(); } else { distancePlayer.State = DistancePlayer.PlayerState.StartedMode; DistanceServerMain.GetEvent <Events.ServerToClient.StartMode>().Fire( data.networkPlayer_, new Distance::Events.ServerToClient.StartMode.Data(ModeStartTime, true) ); } } }); DistanceServerMain.GetEvent <Events.ClientToAllClients.ChatMessage>().Connect((data, info) => { var chatTypeData = new Tuple <DistanceChat.ChatTypeEnum, string>(DistanceChat.ChatTypeEnum.Unknown, "Unknown"); var distancePlayer = GetDistancePlayer(info.sender); if (distancePlayer != null && distancePlayer.Valid) { chatTypeData = DistanceChat.DeduceChatType(data.message_, distancePlayer.Name); } var chat = new DistanceChat(data.message_) { SenderGuid = info.sender.guid, ChatType = chatTypeData.Item1, ChatDescription = chatTypeData.Item2, }; AddChat(chat); }); DistanceServerMain.GetEvent <Events.ClientToAllClients.SetReady>().Connect((data, info) => { // ignore data.player_, it should be sender GetDistancePlayer(info.sender).Ready = data.ready_; }); DistanceServerMain.GetEvent <Events.ClientToServer.SubmitLevelCompatabilityInfo>().Connect((data, info) => { // ignore data.player_, it should be sender var distancePlayer = GetDistancePlayer(info.sender); distancePlayer.LevelCompatibilityInfo = new LevelCompatibilityInfo(data); Log.Debug($"Level compatibility versions test: {data.levelVersion_} : {CurrentLevel.LevelVersion}"); // TODO: write proper level compat check code (the current computed version is incorrect, so version checking is ignored) DistanceServerMain.GetEvent <Events.ServerToClient.UpdatePlayerLevelCompatibilityStatus>().Fire( data.player_, new Distance::Events.ServerToClient.UpdatePlayerLevelCompatibilityStatus.Data(info.sender, distancePlayer.LevelCompatability) ); if (distancePlayer.State == DistancePlayer.PlayerState.WaitingForCompatibilityStatus) { SendPlayerToLevel(distancePlayer.UnityPlayer); } }); DistanceServerMain.GetEvent <Events.ClientToServer.SubmitPlayerData>().Connect((data, info) => { // ignore data.player_, it should be sender var distancePlayer = GetDistancePlayer(info.sender); distancePlayer.RestartTime = -1.0; distancePlayer.Car = new DistanceCar(distancePlayer, data.data_); distancePlayer.Car.MakeNetworker(); DistanceServerMain.GetEvent <Events.ServerToClient.CreatePlayer>().Fire( RPCMode.Others, new Distance::Events.ServerToClient.CreatePlayer.Data(distancePlayer.Car.GetPlayerInitializeData(), distancePlayer.Car.GetPlayerLateInitializeData(), distancePlayer.Index) ); }); }
public override void Start() { Log.Info("Basic Auto Server started!"); Playlist.AddRange(OfficialPlaylist); Filters = new List <FilterWorkshopSearchDelegate>(); ReadSettings(); UnityEngine.MasterServer.dedicatedServer = ReportToMasterServerAsDedicatedServer; Server.MasterServerGameModeOverride = MasterServerGameModeOverride; Server.ServerName = ServerName; Server.MaxPlayers = MaxPlayers; Server.Port = Port; Server.UseNat = UseNat; if (ReportToMasterServerInitialDelay > 0) { Server.ReportToMasterServer = false; DistanceServerMainStarter.Instance.StartCoroutine(SetReportToMasterServerAfterDelay()); } else { Server.ReportToMasterServer = ReportToMasterServer; } lastMasterServerRegistration = DistanceServerMain.UnixTime; if (PrivateServerPassword != null) { UnityEngine.Network.incomingPassword = PrivateServerPassword; } Server.OnPlayerConnectedEvent.Connect(player => { player.Countdown = CountdownTime; player.OnCarAddedEvent.Connect(car => { car.AddExternalData(new LastMoveTimeData(DistanceServerMain.UnixTime)); OnCarAddedEvent.Fire(car); }); }); if (WelcomeMessage != null) { Server.OnPlayerValidatedEvent.Connect(player => { var message = WelcomeMessage; if (message.Contains("$linkcode") && LinkCodeGetter != null) { message = message.Replace("$linkcode", LinkCodeGetter(player)); } message = message.Replace("$player", player.Name); if (!Server.HasModeStarted || player.Car != null) { Server.SayLocalChat(player.UnityPlayer, DistanceChat.Server("AutoServer:Welcome", message)); } else { IEventConnection connection = null; connection = player.OnCarAddedEvent.Connect(car => { Server.SayLocalChat(player.UnityPlayer, DistanceChat.Server("AutoServer:Welcome", message)); connection.Disconnect(); }); } }); } Server.OnLevelStartedEvent.Connect(() => { CountdownTime = -1.0; }); Server.OnModeStartedEvent.Connect(() => { StartingPlayerGuids.Clear(); foreach (var player in Server.ValidPlayers) { if (player.Car != null) { player.Car.GetExternalData <LastMoveTimeData>().LastMoveTime = DistanceServerMain.UnixTime; SetStartingPlayer(player.UnityPlayerGuid, true); } } if (ServerStage == Stage.Starting) { ServerStage = Stage.Started; } }); OnAdvancingToNextLevel.Connect(() => { if (TipMessages.Count > 0) { var tip = TipMessages[currentTip]; currentTip = (currentTip + 1) % TipMessages.Count; Server.SayChat(DistanceChat.Server("AutoServer:Tip", tip)); } }); DistanceServerMain.GetEvent <Events.Instanced.Finished>().Connect((instance, data) => { Log.WriteLine($"{((DistanceCar)instance).Player.Name} finished"); AttemptToAdvanceLevel(); }); if (LoadWorkshopLevels) { DistanceServerMainStarter.Instance.StartCoroutine(DoLoadWorkshopLevels()); } else { StartAutoServer(); } }