private static void ChunkMap(MapState state) { if (state.CurrentChunk == null || state.CurrentChunk.MapName != state.CurrentMap.Name) { Logger.LogDebug("MapName = {0}", state.CurrentMap.Name); state.CurrentChunk = new MapChunkInternal { MapName = state.CurrentMap.Name, StartX = state.CurrentMap.StartX, StartY = state.CurrentMap.StartY, EndX = state.CurrentMap.StartX + state.CurrentMap.Width, EndY = state.CurrentMap.StartY + state.CurrentMap.Height, Width = state.CurrentMap.Width, Height = state.CurrentMap.Height }; } else { state.CurrentChunk.MoveNext(); } var client = ServiceManager.CreateDepotCommunicator(); client.SendCommand(new RdlCommand("MAPCHUNK", state.CurrentMap.Name, state.CurrentChunk.StartX, state.CurrentChunk.StartY, state.IncludeActors), (e) => { if (e.Tags.Count > 0) { if (state.CurrentMap.Name == state.PlayerZone) { if (state.PlayerChunkCallback != null) { int total = (state.CurrentMap.Width > state.CurrentMap.Height) ? state.CurrentMap.Width / MapWidth : state.CurrentMap.Height / MapHeight; int current = (state.CurrentMap.Width > state.CurrentMap.Height) ? (MapWidth - state.CurrentMap.StartX) / MapWidth : (MapHeight - state.CurrentMap.StartY) / MapHeight; state.PlayerChunkCallback(current, total); } } List <RdlPlace> places = e.Tags.GetPlaces(); state.Places.AddRange(places); if (state.CurrentChunk.IsComplete) { // Map download is complete. if (state.CurrentMap.Name == state.PlayerZone && state.PlayerZoneCallback != null) { state.PlayerZoneCallback(); } // Save the map to disk. Logger.LogDebug("Saving map to disk: MapName={0}, PlaceCount={1}", state.CurrentMap.Name, state.Places.Count); StorageManager.WriteMap(state.CurrentMap.Name, state.Places.ToTagCollection()); if (state.MapLoadedCallback != null) { state.MapLoadedCallback(state.CurrentMap.StartX, state.CurrentMap.StartY, state.Places); } // Download the next map. DownloadMaps(state); } else { // Map not completely downloaded, store the tags and re-chunk the next piece of the map. ChunkMap(state); } } client.Close(); }); }