Пример #1
0
        public void ReceiveStateData(byte[] state)
        {
            var rdr = ByteArrayReader.Get(state);

            ReceiveStateData(rdr);
            rdr.Release();
        }
Пример #2
0
        public FullObjectState(byte[] data)
        {
            Data = data;
            var reader = ByteArrayReader.Get(data);

            ObjectId       = reader.ReadUShort();
            ReflectionName = reader.ReadString();
        }
Пример #3
0
        public void DeferredSetFullState()
        {
            _projectiles.Clear();
            var rdr = ByteArrayReader.Get(_projectileArray);

            for (var i = 0; i < _projectileArray.Length; i += 2)
            {
                _projectiles.Add((Projectiles.Projectile)Game.GameObjectsById[rdr.ReadUShort()]);
            }

            rdr.Release();
        }
Пример #4
0
        public void ReceiveStateData(byte[] stateData)
        {
            var rdr = ByteArrayReader.Get(stateData);

            if (GlobalSettings.Debug)
            {
                ReceiveStateDataInternal(rdr);
            }
            else
            {
                try
                {
                    ReceiveStateDataInternal(rdr);
                }
                catch (Exception ex)
                {
                    Game.Logger.Error($"GameObject partial state parsing failed! {ReflectionName}[ID {ObjectId}]", ex);
                }
            }

            rdr.Release();
        }
        public override void ProcessToClientAction(NetConnection client, ActionBase action)
        {
            if (action is CountdownStartedAction)
            {
                var act = action as CountdownStartedAction;
                Client.IsInCountdown          = true;
                Client.RemainingCountdownTime = act.CountdownTime;
            }
            else if (action is FullGameStateSentAction)
            {
                var act = action as FullGameStateSentAction;
                Client._interpolator.ElapsedTime = TimeSpan.MaxValue;
                if (_shouldMakeNewGameOnFullGameState)
                {
                    Client.GameInstance.EngineSettings = act.EngineSettings;
                    Client.GameInstance.FullGameState  = act.State;
                    Client.NeedsToSelectTank           = true;
                }
                else
                {
                    act.State.Apply(Client.GameInstance.Game);
                    //Client.Game.UnsafeTickGameWorld(Client.NetworkClient.ServerConnection.AverageRoundtripTime / 2);
                }
                _shouldMakeNewGameOnFullGameState = false;
            }
            else if (action is GameCreatedAction)
            {
                _shouldMakeNewGameOnFullGameState = true;
            }
            else if (action is GameEndedAction)
            {
                var  act         = action as GameEndedAction;
                Team winningTeam = Client.Game.Gamemode.Teams.FirstOrDefault(
                    t => t.TeamId == act.WinningTeamId) ?? Team.Null;

                if (act.WinningTeamId == Team.Indeterminate.TeamId)
                {
                    winningTeam = Team.Indeterminate;
                }

                typeof(Gamemode).GetProperty(nameof(Gamemode.WinningTeam))
                .SetValue(Client.Game.Gamemode, winningTeam);
                typeof(Gamemode).GetProperty(nameof(Gamemode.GameEnded))
                .SetValue(Client.Game.Gamemode, true);
            }
            else if (action is GamemodeStateChangedAction)
            {
                Client.Game.Gamemode.ReceiveStateData(((GamemodeStateChangedAction)action).NewState);
            }
            else if (action is GameObjectCreatedAction)
            {
                var reader = ByteArrayReader.Get(((GameObjectCreatedAction)action).State.Data);
                GameObject.CreateAndAddFromSerializationInformation(
                    Client.Game, reader);
                reader.Release();
            }
            else if (action is GameObjectDestroyedAction)
            {
                var act = action as GameObjectDestroyedAction;
                if (Client.Game.GameObjectsById.ContainsKey(act.ObjectId))
                {
                    Client.Game.RemoveGameObject(
                        Client.Game.GameObjectsById[act.ObjectId], null, true);
                }
            }
            else if (action is GameObjectDestructionEndedAction)
            {
                var act = action as GameObjectDestructionEndedAction;
                if (Client.Game.GameObjectsById.ContainsKey(act.ObjectId))
                {
                    Client.Game.ImmediatelyForceObjectDestruction(
                        Client.Game.GameObjectsById[act.ObjectId]);
                }
            }
            else if (action is GameStartedAction)
            {
                Client.Game.BeginGame(false);
            }
            else if (action is ObjectBasicPropertyChangedAction)
            {
                var act = action as ObjectBasicPropertyChangedAction;
                if (!Client.Game.GameObjectsById.ContainsKey(act.ObjectId))
                {
                    return;
                }

                var obj = Client.Game.GameObjectsById[act.ObjectId];

                switch (act.EventType)
                {
                case GameObject.BasicPropertyChangeEventType.AngularVelocity:
                    obj.AngularVelocity = act.FloatValue;
                    break;

                case GameObject.BasicPropertyChangeEventType.Health:
                    obj.Health = act.FloatValue;
                    break;

                case GameObject.BasicPropertyChangeEventType.IsSensor:
                    obj.IsSensor = act.BoolValue;
                    break;

                case GameObject.BasicPropertyChangeEventType.IsStatic:
                    obj.IsStatic = act.BoolValue;
                    break;

                case GameObject.BasicPropertyChangeEventType.LinearVelocity:
                    obj.LinearVelocity = act.VectorValue;
                    break;

                case GameObject.BasicPropertyChangeEventType.Position:
                    obj.Position = act.VectorValue;
                    break;

                case GameObject.BasicPropertyChangeEventType.Restitution:
                    obj.Restitution = act.FloatValue;
                    break;

                case GameObject.BasicPropertyChangeEventType.Rotation:
                    obj.Rotation = act.FloatValue;
                    break;

                case GameObject.BasicPropertyChangeEventType.Size:
                    obj.Size = act.VectorValue;
                    break;
                }
            }
            else if (action is ObjectStateChangedAction)
            {
                var act = action as ObjectStateChangedAction;
                if (!Client.Game.GameObjectsById.ContainsKey(
                        act.ObjectId))
                {
                    return;
                }

                Client.Game.GameObjectsById[act.ObjectId]
                .ReceiveStateData(act.PrivateData);
            }
            else if (action is PartialGameStateUpdateAction)
            {
                var act = action as PartialGameStateUpdateAction;
                Client._interpolator.Compute(Client.Game, act.StatePartial);
                //Client.NetworkClient.ServerConnection.AverageRoundtripTime / 2);
            }
            else if (action is PlayerAllowedTankTypesSentAction)
            {
                var act = action as PlayerAllowedTankTypesSentAction;
                Client.Player.AllowedTankTypes = act.AllowedTankTypeReflectionNames;
            }
            else if (action is PlayerInputChangedAction)
            {
                var act = action as PlayerInputChangedAction;
                if (Client.Game.FindPlayer(act.PlayerId) == null)
                {
                    return;                                               //disregard: player not found
                }
                //if (act.PlayerId == Client.PlayerId) return;
                Client.Game.InjectPlayerInput(act.PlayerId, act.InputState);
            }
            else if (action is PlayerUpdateAction)
            {
                return;

                var act = action as PlayerUpdateAction;
                if (Client.Game.FindPlayer(act.Player.Id) != null)
                {
                    act.Player.Apply(Client.Game.FindPlayer <NetworkPlayer>(act.Player.Id));
                    Client.Game.Gamemode.FullState = act.GamemodeState;
                    act.Player.ApplySecondPass(Client.Game.FindPlayer <NetworkPlayer>(act.Player.Id), Client.Game);
                    return; //update: already exists
                }
                Client.Game.AddPlayer(act.Player.ToNetworkPlayer());
                Client.Game.Gamemode.FullState = act.GamemodeState;
                act.Player.ApplySecondPass(
                    (NetworkPlayer)Client.Game.PlayersById[act.Player.Id], Client.Game);
            }
            else if (action is PlayerLeftAction)
            {
                var act = action as PlayerLeftAction;
                if (Client.Game.FindPlayer(act.PlayerId) == null)
                {
                    return;
                }

                Client.Game.Gamemode.FullState = act.GamemodeState;
                Client.Game.RemovePlayer(Client.Game.FindPlayer(act.PlayerId));
            }
            else if (action is PlayerReadyToStartChangedAction)
            {
                var act = action as PlayerReadyToStartChangedAction;
                if (Client.Game.FindPlayer(act.PlayerId) == null)
                {
                    return;
                }
                Client.Game.FindPlayer <NetworkPlayer>(act.PlayerId)
                .IsReady = act.IsReadyToStart;
            }
            else if (action is PlayerSelectedTankAction)
            {
                var act = action as PlayerSelectedTankAction;
                if (Client.Game.FindPlayer(act.PlayerId) == null)
                {
                    return;
                }
                Client.Game.FindPlayer(act.PlayerId)
                .SelectedTankReflectionName = act.TankType;
            }
            else if (action is PlayerTankSelectionAcknowledgedAction)
            {
                var act = action as PlayerTankSelectionAcknowledgedAction;
                Client.NeedsToSelectTank = !act.WasAccepted;
            }
            else if (action is ReceivedChatMessageAction)
            {
                var act = action as ReceivedChatMessageAction;
                Client.Chat.AddMessage(new Chat.ChatMessage()
                {
                    Message  = act.Message,
                    SenderId = act.SenderId
                });
            }
            else if (action is TimescaleChangedAction)
            {
                var act = action as TimescaleChangedAction;
                Client.Game.Timescale = act.Timescale;
            }
        }
Пример #6
0
        public void Apply(GameCore game)
        {
            game.Gamemode.FullState = GamemodeState;

            GameCore.TimescaleValue timescale = new GameCore.TimescaleValue(TimescaleValue, TimescaleString);
            foreach (var ts in GameCore.TimescaleValue.Values)
            {
                if (ts.DisplayString == TimescaleString)
                {
                    timescale = ts;
                }
            }

            game.Timescale           = timescale;
            game.FriendlyFireEnabled = FriendlyFireEnabled;

            //Do it via reflection to keep api private
            typeof(GameCore).GetProperty(nameof(GameCore.Status))
            .SetValue(game, Status);
            //Do this with reflection again because we want to keep the api private (set game time)
            typeof(GameCore).GetProperty(nameof(GameCore.Time))
            .SetValue(game, TimeSpan.FromMilliseconds(CurrentGameTimeMilliseconds));
            //Once again
            typeof(GameCore).GetProperty(nameof(GameCore.HasStarted))
            .SetValue(game, HasStarted);
            //A fourth time, keep the API private
            typeof(GameCore).GetField("_nextObjectId",
                                      System.Reflection.BindingFlags.Default | System.Reflection.BindingFlags.SetField |
                                      System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic)
            .SetValue(game, NextObjectId);
            //And a fifth
            typeof(GameCore).GetField("_gameEndedTime",
                                      System.Reflection.BindingFlags.Default | System.Reflection.BindingFlags.SetField |
                                      System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic)
            .SetValue(game, TimeSpan.FromMilliseconds(GameEndedTime));

            foreach (var player in Players)
            {
                var nwPlayer = new NetworkPlayer();
                if (game.PlayersById.ContainsKey(player.Id) && game.PlayersById[player.Id] is NetworkPlayer)
                {
                    nwPlayer = (NetworkPlayer)game.PlayersById[player.Id];
                }
                else if (game.PlayersById.ContainsKey(player.Id)) //remove because it isn't a networkplayer
                {
                    game.RemovePlayer(player.Id);
                }

                player.Apply(nwPlayer);

                if (!game.PlayersById.ContainsKey(player.Id))
                {
                    game.AddPlayer(nwPlayer);
                }
            }
            var missingPlayers = new List <NetworkPlayer>();

            foreach (var plr in game.Players)
            {
                bool found = false;
                foreach (var p in Players)
                {
                    if (p.UniqueId == ((NetworkPlayer)plr).UniqueId)
                    {
                        found = true;
                    }
                }
                if (!found)
                {
                    missingPlayers.Add((NetworkPlayer)plr);
                }
            }
            foreach (var plr in missingPlayers)
            {
                game.RemovePlayer(plr);
            }

            //Add all of the game objects
            foreach (var fullState in ObjectStates)
            {
                if (!game.GameObjectsById.ContainsKey(fullState.ObjectId))
                {
                    var rdr = ByteArrayReader.Get(fullState.Data);
                    GameObject.CreateAndAddFromSerializationInformation(game, rdr, true);
                    rdr.Release();
                }
                else
                {
                    game.GameObjectsById[fullState.ObjectId].FullState = fullState.Data;
                }
            }

            ApplyDestruction(game);

            var playersByTeam = new Dictionary <short, List <NetworkPlayer> >();

            foreach (var player in Players)
            {
                if (!playersByTeam.ContainsKey(player.TeamId))
                {
                    playersByTeam.Add(player.TeamId, new List <NetworkPlayer>());
                }

                playersByTeam[player.TeamId].Add(player.PlayerObject);
            }

            foreach (var kvp in playersByTeam)
            {
                var team = FindTeam(game.Gamemode.Teams, kvp.Key);
                team.Players = kvp.Value.ToArray();
            }

            foreach (var player in Players)
            {
                player.ApplySecondPass(player.PlayerObject, game);
            }

            game.Gamemode.DeferredSetFullState();
            foreach (var obj in game.GameObjects)
            {
                obj.SetPostInitStateData();
            }
        }