public static List <object> Serialize( GameEntity playerEntity, EntityState state, PlayerSnapshot snapshot, List <object> serializedLevel, SerializationContext context) { var manager = context.Manager; var player = playerEntity.Player; var being = playerEntity.Being; List <object> properties; if (state == EntityState.Added) { properties = new List <object>(14) { (int)state }; properties.Add(player.EntityId); properties.Add(player.ProperName); properties.Add(player.Game.CurrentTick); properties.Add(serializedLevel); properties.Add(manager.RacesToBeingRelationship[playerEntity.Id].Values .Select(r => RaceSnapshot.Serialize(r, null, context)).ToList()); properties.Add(manager.EntityItemsToContainerRelationship[playerEntity.Id] .Select(t => InventoryItemSnapshot.Serialize(t, null, null, context)).ToList()); properties.Add(GetSlottedAbilities(playerEntity, manager) .Select(a => AbilitySnapshot.Serialize(a, null, context)).ToList()); // TODO: Group log entries for the same tick // TODO: Only send entries since last player turn properties.Add(GetLogEntries(player) .Select(e => LogEntrySnapshot.Serialize(e, null, context)).ToList()); properties.Add(player.NextActionTick); properties.Add(player.NextLevelXP); properties.Add(being.ExperiencePoints); properties.Add(being.HitPoints); properties.Add(being.HitPointMaximum); properties.Add(being.EnergyPoints); properties.Add(being.EnergyPointMaximum); properties.Add(being.ReservedEnergyPoints); return(properties); } properties = new List <object>(3) { (int)state, snapshot.SnapshotTick, player.Game.CurrentTick }; var playerEntry = context.DbContext.Entry(player); var i = 2; if (serializedLevel != null) { properties.Add(i); properties.Add(serializedLevel); } i++; var serializedRaces = GameTransmissionProtocol.Serialize( manager.RacesToBeingRelationship[playerEntity.Id].Values, snapshot.RacesSnapshot, RaceSnapshot.Serialize, context); if (serializedRaces.Count > 0) { properties.Add(i); properties.Add(serializedRaces); } i++; var serializedItems = GameTransmissionProtocol.Serialize( manager.EntityItemsToContainerRelationship[playerEntity.Id], snapshot.ItemsSnapshot, InventoryItemSnapshot.Serialize, context); if (serializedItems.Count > 0) { properties.Add(i); properties.Add(serializedItems); } i++; var serializedAbilities = GameTransmissionProtocol.Serialize( GetSlottedAbilities(playerEntity, manager), snapshot.AbilitiesSnapshot, AbilitySnapshot.Serialize, context); if (serializedAbilities.Count > 0) { properties.Add(i); properties.Add(serializedAbilities); } i++; var serializedLog = GameTransmissionProtocol.Serialize( GetLogEntries(player), snapshot.LogEntriesSnapshot, LogEntrySnapshot.Serialize, context); if (serializedLog.Count > 0) { properties.Add(i); properties.Add(serializedLog); } i++; var nextActionTick = playerEntry.Property(nameof(PlayerComponent.NextActionTick)); if (nextActionTick.IsModified) { properties.Add(i); properties.Add(player.NextActionTick); } i++; var nextLevelXP = playerEntry.Property(nameof(PlayerComponent.NextLevelXP)); if (nextLevelXP.IsModified) { properties.Add(i); properties.Add(player.NextLevelXP); } var beingEntry = context.DbContext.Entry(being); if (beingEntry.State != EntityState.Unchanged) { i++; var xp = beingEntry.Property(nameof(BeingComponent.ExperiencePoints)); if (xp.IsModified) { properties.Add(i); properties.Add(being.ExperiencePoints); } i++; var hitPoints = beingEntry.Property(nameof(BeingComponent.HitPoints)); if (hitPoints.IsModified) { properties.Add(i); properties.Add(being.HitPoints); } i++; var hitPointMaximum = beingEntry.Property(nameof(BeingComponent.HitPointMaximum)); if (hitPointMaximum.IsModified) { properties.Add(i); properties.Add(being.HitPointMaximum); } i++; var energyPoints = beingEntry.Property(nameof(BeingComponent.EnergyPoints)); if (energyPoints.IsModified) { properties.Add(i); properties.Add(being.EnergyPoints); } i++; var energyPointMaximum = beingEntry.Property(nameof(BeingComponent.EnergyPointMaximum)); if (energyPointMaximum.IsModified) { properties.Add(i); properties.Add(being.EnergyPointMaximum); } i++; var reservedEnergyPoints = beingEntry.Property(nameof(BeingComponent.ReservedEnergyPoints)); if (reservedEnergyPoints.IsModified) { properties.Add(i); properties.Add(being.ReservedEnergyPoints); } } return(properties); }
public GameHub(GameDbContext dbContext, GameServices gameServices, GameTransmissionProtocol protocol) { _dbContext = dbContext; _gameServices = gameServices; _protocol = protocol; }
public static List <object> Serialize( GameEntity levelEntity, EntityState?state, LevelSnapshot snapshot, SerializationContext context) { var manager = context.Manager; var level = levelEntity.Level; List <object> properties; switch (state) { case null: case EntityState.Added: var knownTerrain = new List <short>(); for (short j = 0; j < level.KnownTerrain.Length; j++) { var feature = level.KnownTerrain[j]; if (feature != (byte)MapFeature.Unexplored) { knownTerrain.Add(j); knownTerrain.Add(feature); } } var wallNeighbours = new List <short>(); for (short j = 0; j < level.WallNeighbours.Length; j++) { if (level.KnownTerrain[j] == (byte)MapFeature.Unexplored) { continue; } var neighbours = level.WallNeighbours[j] & (byte)DirectionFlags.Cross; if (neighbours != (byte)DirectionFlags.None) { wallNeighbours.Add(j); wallNeighbours.Add((byte)neighbours); } } var visibleTerrain = new List <short>(); for (short j = 0; j < level.VisibleTerrain.Length; j++) { var visibility = level.VisibleTerrain[j]; if (visibility != 0) { visibleTerrain.Add(j); visibleTerrain.Add(visibility); } } properties = state == null ? new List <object>(10) : new List <object>(11) { (int)state }; properties.Add(GetActors(levelEntity, manager) .Select(a => LevelActorSnapshot.Serialize(a, null, context)).ToList()); properties.Add(GetItems(levelEntity, manager) .Select(t => LevelItemSnapshot.Serialize(t, null, null, context)).ToList()); properties.Add(GetConnections(levelEntity, manager) .Select(c => ConnectionSnapshot.Serialize(c, null, context)).ToList()); properties.Add(knownTerrain); properties.Add(wallNeighbours); properties.Add(visibleTerrain); properties.Add(level.BranchName); properties.Add(level.Depth); properties.Add(level.Width); properties.Add(level.Height); return(properties); default: var levelEntry = context.DbContext.Entry(level); properties = new List <object> { (int)state }; var i = 2; var serializedActors = GameTransmissionProtocol.Serialize( GetActors(levelEntity, manager), snapshot.ActorsSnapshot, LevelActorSnapshot.Serialize, context); if (serializedActors.Count > 0) { properties.Add(i); properties.Add(serializedActors); } i++; var serializedItems = GameTransmissionProtocol.Serialize( GetItems(levelEntity, manager), snapshot.ItemsSnapshot, LevelItemSnapshot.Serialize, context); if (serializedItems.Count > 0) { properties.Add(i); properties.Add(serializedItems); } i++; var serializedConnections = GameTransmissionProtocol.Serialize( GetConnections(levelEntity, manager), snapshot.ConnectionsSnapshot, ConnectionSnapshot.Serialize, context); if (serializedConnections.Count > 0) { properties.Add(i); properties.Add(serializedConnections); } if (levelEntry.State != EntityState.Unchanged) { i++; var wallNeighboursChanges = new List <object>(); var knownTerrainChanges = new List <object>(level.KnownTerrainChanges.Count * 2); if (level.KnownTerrainChanges.Count > 0) { foreach (var terrainChange in level.KnownTerrainChanges) { knownTerrainChanges.Add(terrainChange.Key); knownTerrainChanges.Add(terrainChange.Value); wallNeighboursChanges.Add(terrainChange.Key); wallNeighboursChanges.Add(level.WallNeighbours[terrainChange.Key] & (byte)DirectionFlags.Cross); } } if (level.TerrainChanges.Count > 0) { foreach (var terrainChange in level.TerrainChanges) { if (level.VisibleTerrain[terrainChange.Key] == 0) { continue; } knownTerrainChanges.Add(terrainChange.Key); knownTerrainChanges.Add(terrainChange.Value); } } if (knownTerrainChanges.Count > 0) { properties.Add(i); properties.Add(knownTerrainChanges); } i++; if (level.WallNeighboursChanges.Count > 0) { foreach (var wallNeighboursChange in level.WallNeighboursChanges) { if (level.VisibleTerrain[wallNeighboursChange.Key] == 0) { continue; } wallNeighboursChanges.Add(wallNeighboursChange.Key); wallNeighboursChanges.Add(wallNeighboursChange.Value & (byte)DirectionFlags.Cross); } } if (wallNeighboursChanges.Count > 0) { properties.Add(i); properties.Add(wallNeighboursChanges); } i++; if (level.VisibleTerrainChanges.Count > 0) { properties.Add(i); var changes = new object[level.VisibleTerrainChanges.Count * 2]; var j = 0; foreach (var visibleTerrainChange in level.VisibleTerrainChanges) { changes[j++] = visibleTerrainChange.Key; changes[j++] = visibleTerrainChange.Value; } properties.Add(changes); } } return(properties.Count > 1 ? properties : null); } }