コード例 #1
0
    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);
    }
コード例 #2
0
    public static bool CheckCancelled(LocalEvent <Cancellable> evt)
    {
        var cancellable = new Cancellable();

        evt.Fire(cancellable);
        return(cancellable.IsCancelled);
    }
コード例 #3
0
    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);
    }
コード例 #4
0
 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);
 }
コード例 #5
0
 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);
 }
コード例 #6
0
        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();
                }
            })
                );
        }
コード例 #7
0
 public void OnMasterServer(MasterServerEvent evt)
 {
     OnMasterServerEvent.Fire(evt);
 }
コード例 #8
0
 public void OnFailedToConnectToMasterServer(NetworkConnectionError error)
 {
     OnFailedToConnectToMasterServerEvent.Fire(error);
 }
コード例 #9
0
    ///

    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)
                );
        });
    }
コード例 #10
0
        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();
            }
        }