/// <see cref="IMapLoader.LoadMapHeader"/> public MapHeader LoadMapHeader(byte[] data) { if (!this.initThreadStarted) { throw new InvalidOperationException("Component has not yet been started!"); } this.initThread.Join(); if (data == null) { throw new ArgumentNullException("data"); } int offset = 0; while (offset < data.Length) { int parsedBytes; RCPackage package = RCPackage.Parse(data, offset, data.Length - offset, out parsedBytes); if (package == null || !package.IsCommitted) { throw new MapException("Syntax error!"); } offset += parsedBytes; if (package.PackageFormat.ID == MapFileFormat.MAP_HEADER) { return(MapHeader.FromPackage(package)); } } throw new MapException("Map header information not found!"); }
/// <see cref="IMapLoader.LoadMap"/> public IMapAccess LoadMap(ITileSet tileset, byte[] data) { if (!this.initThreadStarted) { throw new InvalidOperationException("Component has not yet been started!"); } this.initThread.Join(); if (tileset == null) { throw new ArgumentNullException("tileset"); } if (data == null) { throw new ArgumentNullException("data"); } /// Load the packages from the byte array. RCPackage mapHeaderPackage = null; RCPackage isotileListPackage = null; RCPackage terrainObjListPackage = null; int offset = 0; while (offset < data.Length) { int parsedBytes; RCPackage package = RCPackage.Parse(data, offset, data.Length - offset, out parsedBytes); if (package == null || !package.IsCommitted) { throw new MapException("Syntax error!"); } offset += parsedBytes; if (package.PackageFormat.ID == MapFileFormat.MAP_HEADER) { mapHeaderPackage = package; } else if (package.PackageFormat.ID == MapFileFormat.ISOTILE_LIST) { isotileListPackage = package; } else if (package.PackageFormat.ID == MapFileFormat.TERRAINOBJ_LIST) { terrainObjListPackage = package; } } /// Validate the packages. if (mapHeaderPackage == null) { throw new MapException("Syntax error: map header is missing!"); } if (isotileListPackage == null) { throw new MapException("Syntax error: isometric-tile-list is missing!"); } if (terrainObjListPackage == null) { throw new MapException("Syntax error: terrain-object-list is missing!"); } /// Validate the map header. MapHeader mapHeader = MapHeader.FromPackage(mapHeaderPackage); if (mapHeader.AppVersion > new Version(ConstantsTable.Get <string>("RC.App.Version"))) { throw new MapException(string.Format("Incompatible map version: {0}!", mapHeader.AppVersion)); } if (mapHeader.TilesetName != tileset.Name) { throw new ArgumentException(string.Format("The given tileset '{0}' has to equal with the map tileset '{1}'!", tileset.Name, mapHeader.TilesetName), "tileset"); } if (mapHeader.MapSize.X > MapStructure.MAX_MAPSIZE || mapHeader.MapSize.Y > MapStructure.MAX_MAPSIZE) { throw new MapException(string.Format("Map size exceeds the limits: {0}x{0}!", MapStructure.MAX_MAPSIZE)); } MapAccess retObj = new MapAccess(mapHeader.MapName, this.mapStructure); this.mapStructure.BeginOpen(tileset, mapHeader.MapSize); this.LoadIsoTiles(isotileListPackage); this.mapStructure.EndOpen(); this.LoadTerrainObjects(terrainObjListPackage, retObj); // TODO: validate MapHeader.MaxPlayers! // TODO: validate the MapHeader checksums! return(retObj); }