Skip to content

Commit

Permalink
Update map serialization to store row IDs for GFX rows that contain z…
Browse files Browse the repository at this point in the history
…ero elements. Fixes login bug where certain maps would always be redownloaded due to mismatched expected length.
  • Loading branch information
ethanmoffat committed Mar 11, 2022
1 parent d1b9dea commit 4d7787c
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 8 deletions.
3 changes: 2 additions & 1 deletion EOLib.IO/Map/IMapFile.cs
Expand Up @@ -9,6 +9,7 @@ public interface IMapFile
IReadOnlyMatrix<TileSpec> Tiles { get; }
IReadOnlyMatrix<WarpMapEntity> Warps { get; }
IReadOnlyDictionary<MapLayer, IReadOnlyMatrix<int>> GFX { get; }
IReadOnlyDictionary<MapLayer, IReadOnlyList<int>> EmptyGFXRows { get; }
IReadOnlyList<NPCSpawnMapEntity> NPCSpawns { get; }
IReadOnlyList<UnknownMapEntity> Unknowns { get; }
IReadOnlyList<ChestSpawnMapEntity> Chests { get; }
Expand All @@ -22,7 +23,7 @@ public interface IMapFile

IMapFile WithWarps(Matrix<WarpMapEntity> warps);

IMapFile WithGFX(Dictionary<MapLayer, Matrix<int>> gfx);
IMapFile WithGFX(Dictionary<MapLayer, Matrix<int>> gfx, Dictionary<MapLayer, List<int>> emptyLayers);

IMapFile WithNPCSpawns(List<NPCSpawnMapEntity> npcSpawns);

Expand Down
11 changes: 10 additions & 1 deletion EOLib.IO/Map/MapFile.cs
Expand Up @@ -13,6 +13,7 @@ public class MapFile : IMapFile
public IReadOnlyMatrix<TileSpec> Tiles => _mutableTiles;
public IReadOnlyMatrix<WarpMapEntity> Warps => _mutableWarps;
public IReadOnlyDictionary<MapLayer, IReadOnlyMatrix<int>> GFX => _readOnlyGFX;
public IReadOnlyDictionary<MapLayer, IReadOnlyList<int>> EmptyGFXRows => _readOnlyEmptyGFXRows;
public IReadOnlyList<NPCSpawnMapEntity> NPCSpawns => _mutableNPCSpawns;
public IReadOnlyList<UnknownMapEntity> Unknowns => _mutableUnknowns;
public IReadOnlyList<ChestSpawnMapEntity> Chests => _mutableChestSpawns;
Expand All @@ -22,6 +23,8 @@ public class MapFile : IMapFile
private Matrix<WarpMapEntity> _mutableWarps;
private Dictionary<MapLayer, Matrix<int>> _mutableGFX;
private IReadOnlyDictionary<MapLayer, IReadOnlyMatrix<int>> _readOnlyGFX;
private Dictionary<MapLayer, List<int>> _mutableEmptyGFXRows;
private IReadOnlyDictionary<MapLayer, IReadOnlyList<int>> _readOnlyEmptyGFXRows;
private List<NPCSpawnMapEntity> _mutableNPCSpawns;
private List<UnknownMapEntity> _mutableUnknowns;
private List<ChestSpawnMapEntity> _mutableChestSpawns;
Expand All @@ -32,6 +35,7 @@ public MapFile()
Matrix<TileSpec>.Empty,
Matrix<WarpMapEntity>.Empty,
new Dictionary<MapLayer, Matrix<int>>(),
new Dictionary<MapLayer, List<int>>(),
new List<NPCSpawnMapEntity>(),
new List<UnknownMapEntity>(),
new List<ChestSpawnMapEntity>(),
Expand All @@ -46,6 +50,7 @@ public MapFile()
Matrix<TileSpec> tiles,
Matrix<WarpMapEntity> warps,
Dictionary<MapLayer, Matrix<int>> gfx,
Dictionary<MapLayer, List<int>> emptyGFXRows,
List<NPCSpawnMapEntity> npcSpawns,
List<UnknownMapEntity> unknowns,
List<ChestSpawnMapEntity> chests,
Expand All @@ -55,6 +60,7 @@ public MapFile()
_mutableTiles = tiles;
_mutableWarps = warps;
_mutableGFX = gfx;
_mutableEmptyGFXRows = emptyGFXRows;
SetReadOnlyGFX();
_mutableNPCSpawns = npcSpawns;
_mutableUnknowns = unknowns;
Expand Down Expand Up @@ -89,10 +95,11 @@ public IMapFile WithWarps(Matrix<WarpMapEntity> warps)
return newMap;
}

public IMapFile WithGFX(Dictionary<MapLayer, Matrix<int>> gfx)
public IMapFile WithGFX(Dictionary<MapLayer, Matrix<int>> gfx, Dictionary<MapLayer, List<int>> emptyRows)
{
var newMap = MakeCopy(this);
newMap._mutableGFX = gfx;
newMap._mutableEmptyGFXRows = emptyRows;
SetReadOnlyGFX();
return newMap;
}
Expand Down Expand Up @@ -177,6 +184,7 @@ private static MapFile MakeCopy(MapFile source)
source._mutableTiles,
source._mutableWarps,
source._mutableGFX,
source._mutableEmptyGFXRows,
source._mutableNPCSpawns,
source._mutableUnknowns,
source._mutableChestSpawns,
Expand All @@ -186,6 +194,7 @@ private static MapFile MakeCopy(MapFile source)
private void SetReadOnlyGFX()
{
_readOnlyGFX = _mutableGFX.ToDictionary(k => k.Key, v => (IReadOnlyMatrix<int>)v.Value);
_readOnlyEmptyGFXRows = _mutableEmptyGFXRows.ToDictionary(k => k.Key, v => (IReadOnlyList<int>)v.Value);
}
}
}
30 changes: 25 additions & 5 deletions EOLib.IO/Services/Serializers/MapFileSerializer.cs
Expand Up @@ -85,7 +85,7 @@ public IMapFile DeserializeFromByteArray(byte[] data)
var mapChests = ReadMapChests(ms);
var tileSpecs = ReadTileSpecs(ms, properties);
var warpTiles = ReadWarpTiles(ms, properties);
var gfxLayers = ReadGFXLayers(ms, properties);
var (gfxLayers, emptyLayers) = ReadGFXLayers(ms, properties);

var mapSigns = new List<SignMapEntity>();
if (ms.Position < ms.Length)
Expand All @@ -101,7 +101,7 @@ public IMapFile DeserializeFromByteArray(byte[] data)
.WithChests(mapChests)
.WithTiles(tileSpecs)
.WithWarps(warpTiles)
.WithGFX(gfxLayers)
.WithGFX(gfxLayers, emptyLayers)
.WithSigns(mapSigns);
}
}
Expand Down Expand Up @@ -204,9 +204,10 @@ private Matrix<WarpMapEntity> ReadWarpTiles(MemoryStream ms, IMapFileProperties
return warps;
}

private Dictionary<MapLayer, Matrix<int>> ReadGFXLayers(MemoryStream ms, IMapFileProperties properties)
private (Dictionary<MapLayer, Matrix<int>>, Dictionary<MapLayer, List<int>>) ReadGFXLayers(MemoryStream ms, IMapFileProperties properties)
{
var gfx = new Dictionary<MapLayer, Matrix<int>>();
var emptyRows = new Dictionary<MapLayer, List<int>>();

var layers = (MapLayer[])Enum.GetValues(typeof(MapLayer));
var twoByteBuffer = new byte[2];
Expand All @@ -223,6 +224,14 @@ private Matrix<WarpMapEntity> ReadWarpTiles(MemoryStream ms, IMapFileProperties
var y = _numberEncoderService.DecodeNumber((byte)ms.ReadByte());
var numberOfColsThisLayer = _numberEncoderService.DecodeNumber((byte)ms.ReadByte());

if (numberOfColsThisLayer == 0)
{
if (!emptyRows.ContainsKey(layer))
emptyRows.Add(layer, new List<int>());

emptyRows[layer].Add(y);
}

for (int j = 0; j < numberOfColsThisLayer; ++j)
{
var x = _numberEncoderService.DecodeNumber((byte)ms.ReadByte());
Expand All @@ -236,7 +245,7 @@ private Matrix<WarpMapEntity> ReadWarpTiles(MemoryStream ms, IMapFileProperties
}
}

return gfx;
return (gfx, emptyRows);
}

private List<SignMapEntity> ReadMapSigns(MemoryStream ms)
Expand Down Expand Up @@ -365,7 +374,9 @@ private List<byte> WriteGFXLayers(IMapFile mapFile)
.Where(rowList => rowList.EntityItems.Any(item => item != DEFAULT_GFX))
.ToList();

ret.AddRange(_numberEncoderService.EncodeNumber(gfxRowsForLayer.Count, 1));
var rowsForLayerCount = gfxRowsForLayer.Count + (mapFile.EmptyGFXRows.ContainsKey(layer) ? mapFile.EmptyGFXRows[layer].Count : 0);
ret.AddRange(_numberEncoderService.EncodeNumber(rowsForLayerCount, 1));

foreach (var row in gfxRowsForLayer)
{
var entityItems = row.EntityItems
Expand All @@ -381,6 +392,15 @@ private List<byte> WriteGFXLayers(IMapFile mapFile)
ret.AddRange(_numberEncoderService.EncodeNumber(item.Value, 2));
}
}

if (mapFile.EmptyGFXRows.ContainsKey(layer))
{
foreach (var emptyLayer in mapFile.EmptyGFXRows[layer])
{
ret.AddRange(_numberEncoderService.EncodeNumber(emptyLayer, 1));
ret.AddRange(_numberEncoderService.EncodeNumber(0, 1));
}
}
}
return ret;
}
Expand Down
1 change: 0 additions & 1 deletion EOLib/Domain/Map/CurrentMapProvider.cs
Expand Up @@ -17,7 +17,6 @@ public class CurrentMapProvider : ICurrentMapProvider
_mapFileProvider = mapFileProvider;
}


public IMapFile CurrentMap => _mapFileProvider.MapFiles[_currentMapStateProvider.CurrentMapID];
}

Expand Down

0 comments on commit 4d7787c

Please sign in to comment.