public void ReceiveStateData(byte[] state) { var rdr = ByteArrayReader.Get(state); ReceiveStateData(rdr); rdr.Release(); }
public FullObjectState(byte[] data) { Data = data; var reader = ByteArrayReader.Get(data); ObjectId = reader.ReadUShort(); ReflectionName = reader.ReadString(); }
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(); }
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; } }
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(); } }