Пример #1
0
        public ServerPlayer AddPlayer(ServerPlayer player)
        {
            if (Players.Contains(player))
            {
                return(player);
            }

            player.Player.Id = Game.AvailablePlayerId;
            Game.AddPlayer(player.Player);
            _players.Add(player);

            //Queue the game state for them, delaying 1sec for connect messages to be processed fully
            Timers.CreateTimer(a =>
            {
                MessageProcessor.SendPrivateMessage(player,
                                                    new GameCreatedAction());
                MessageProcessor.SendPrivateMessage(player,
                                                    new FullGameStateSentAction(Game));
            }, TimeSpan.FromSeconds(1));
            //Announce that they joined
            ChatHandler.SendMessage($"{player.Player.Username} joined the server");

            player.LastSentState             = PseudoFullGameWorldState.Create(Game);
            player.Player.OnPropertyChanged -= Player_PropertyChanged;
            player.Player.OnPropertyChanged += Player_PropertyChanged;

            MessageProcessor.SendMessage(new PlayerUpdateAction(player.Player, Game));

            //Create a state sync loop
            Timers.CreateReccuringTimer(t =>
            {
                if (Players.Contains(player))
                {
                    var message          = new PartialGameStateUpdateAction(Game, player.LastSentState);
                    player.LastSentState = message.StatePartial;
                    //do state sync
                    MessageProcessor.SendPrivateMessage(player, message);
                }
                else
                {
                    //Disconnect
                    Timers.RemoveTimer(t);
                }
            }, Configuration.StateSyncRate);

            //Special case for hotjoin

            if (Game.HasStarted && Game.Gamemode.HotJoinEnabled)
            {
                var time = ServerSettings.Instance.TimeToWaitForPlayersReady.Value;
                Timers.CreateReccuringTimer((t) =>
                {
                    if (!Game.Running || !Game.Gamemode.HotJoinEnabled)
                    {
                        t.Remove();
                    }

                    MessageProcessor.SendPrivateMessage(player, new CountdownStartedAction(time));
                    time -= TimeSpan.FromMilliseconds(16.666);

                    if (time < TimeSpan.Zero)
                    {
                        t.Remove();
                    }
                    if (player.IsReady)
                    {
                        t.Remove();
                        MessageProcessor.SendPrivateMessage(player, new CountdownStartedAction(TimeSpan.FromSeconds(-1)));
                    }
                }, TimeSpan.FromSeconds(0.01));
            }

            return(player);
        }