Commit 5ccd4c43035df90b493ebdfd40bf9afdc51579c0
1 parent
36186f24
Fixed region and relative chunk calculation from coords. Fixed bug when chunks w…
…ere not generated in region file. Fixed potential crash when header length is 0
Showing
3 changed files
with
28 additions
and
11 deletions
chunk.c
... | ... | @@ -8,8 +8,8 @@ ssize_t loadChunk(const char* regionFolder, ChunkID chunk, void** chunkData); |
8 | 8 | |
9 | 9 | RegionID translateChunkToRegion(int x, int z) { |
10 | 10 | RegionID region; |
11 | - region.x = x/CHUNKS_PER_REGION; | |
12 | - region.z = z/CHUNKS_PER_REGION; | |
11 | + region.x = floor((double)x/CHUNKS_PER_REGION); | |
12 | + region.z = floor((double)z/CHUNKS_PER_REGION); | |
13 | 13 | return region; |
14 | 14 | } |
15 | 15 | |
... | ... | @@ -20,16 +20,16 @@ RegionID translateCoordsToRegion(double x, double y, double z) { |
20 | 20 | |
21 | 21 | ChunkID translateCoordsToChunk(double x, double y, double z) { |
22 | 22 | ChunkID chunk; |
23 | - chunk.x = x/BLOCKS_PER_CHUNK; | |
24 | - chunk.z = z/BLOCKS_PER_CHUNK; | |
23 | + chunk.x = floor((double)x/BLOCKS_PER_CHUNK); | |
24 | + chunk.z = floor((double)z/BLOCKS_PER_CHUNK); | |
25 | 25 | return chunk; |
26 | 26 | } |
27 | 27 | |
28 | 28 | int overwriteChunk(const char* regionFolder, ChunkID chunk, void* chunkData, size_t chunkLength) { |
29 | 29 | RegionID region = translateChunkToRegion(chunk.x,chunk.z); |
30 | 30 | ChunkID relativeChunk; |
31 | - relativeChunk.x = chunk.x % 32; | |
32 | - relativeChunk.z = chunk.z % 32; | |
31 | + relativeChunk.x = chunk.x & 31; | |
32 | + relativeChunk.z = chunk.z & 31; | |
33 | 33 | |
34 | 34 | char* regionFilename = calloc(MAX_REGION_FILENAME_LENGTH + strlen(regionFolder),sizeof(char)); |
35 | 35 | sprintf(regionFilename,"%s/r.%d.%d.mca",regionFolder,region.x,region.z); |
... | ... | @@ -110,8 +110,8 @@ int overwriteChunk(const char* regionFolder, ChunkID chunk, void* chunkData, siz |
110 | 110 | ssize_t loadChunk(const char* regionFolder, ChunkID chunk, void** chunkData) { |
111 | 111 | RegionID region = translateChunkToRegion(chunk.x,chunk.z); |
112 | 112 | ChunkID relativeChunk; |
113 | - relativeChunk.x = chunk.x % 32; | |
114 | - relativeChunk.z = chunk.z % 32; | |
113 | + relativeChunk.x = chunk.x & 31; | |
114 | + relativeChunk.z = chunk.z & 31; | |
115 | 115 | |
116 | 116 | char* regionFilename = calloc(MAX_REGION_FILENAME_LENGTH + strlen(regionFolder),sizeof(char)); |
117 | 117 | sprintf(regionFilename,"%s/r.%d.%d.mca",regionFolder,region.x,region.z); |
... | ... | @@ -135,6 +135,11 @@ ssize_t loadChunk(const char* regionFolder, ChunkID chunk, void** chunkData) { |
135 | 135 | return -3; |
136 | 136 | } |
137 | 137 | chunkHeaderOffset = (__bswap_32(chunkHeaderOffset & 0x00FFFFFF) >> 8) * CHUNK_SECTOR_SIZE; |
138 | + if(chunkHeaderOffset == 0) { | |
139 | + // Chunk not present. Hasn't been generated | |
140 | + close(fd); | |
141 | + return 0; | |
142 | + } | |
138 | 143 | |
139 | 144 | if(lseek(fd,chunkHeaderOffset,SEEK_SET) == -1) { |
140 | 145 | close(fd); |
... | ... | @@ -150,6 +155,16 @@ ssize_t loadChunk(const char* regionFolder, ChunkID chunk, void** chunkData) { |
150 | 155 | } |
151 | 156 | header.length = __bswap_32(header.length); |
152 | 157 | ssize_t chunkLength = header.length; |
158 | + if(header.compressionType != COMPRESSION_TYPE_ZLIB && header.compressionType != COMPRESSION_TYPE_GZIP) { | |
159 | + fprintf(stderr, "Invalid compression method. Proably reading the wrong data for the header\n"); | |
160 | + close(fd); | |
161 | + return -6; | |
162 | + } | |
163 | + if(header.length == 0) { | |
164 | + fprintf(stderr, "Header length is 0. Probably reading the wrong data for the header\n"); | |
165 | + close(fd); | |
166 | + return -7; | |
167 | + } | |
153 | 168 | |
154 | 169 | void* compressedChunk = calloc(chunkLength,sizeof(char)); |
155 | 170 | ssize_t nRead = 0; |
... | ... | @@ -163,7 +178,7 @@ ssize_t loadChunk(const char* regionFolder, ChunkID chunk, void** chunkData) { |
163 | 178 | fprintf(stderr,"Unable to read chunk: %s\n",strerror(errno)); |
164 | 179 | close(fd); |
165 | 180 | free(compressedChunk); |
166 | - return -6; | |
181 | + return -8; | |
167 | 182 | } |
168 | 183 | totalRead += nRead; |
169 | 184 | } |
... | ... | @@ -174,7 +189,8 @@ ssize_t loadChunk(const char* regionFolder, ChunkID chunk, void** chunkData) { |
174 | 189 | |
175 | 190 | if(chunkLength <= 0) { |
176 | 191 | fprintf(stderr,"Error while decompressing chunk\n"); |
177 | - return -8; | |
192 | + free(compressedChunk); | |
193 | + return -9; | |
178 | 194 | } |
179 | 195 | free(compressedChunk); |
180 | 196 | ... | ... |
chunk.h
compression.c
... | ... | @@ -45,7 +45,7 @@ ssize_t inflateGzip(void* compData, size_t compDataLen, void** unCompData, int h |
45 | 45 | strm.avail_out = uncompLength - strm.total_out; |
46 | 46 | |
47 | 47 | // Inflate another chunk. |
48 | - err = inflate (&strm, Z_SYNC_FLUSH); | |
48 | + err = inflate(&strm, Z_SYNC_FLUSH); | |
49 | 49 | if(err != Z_OK && err != Z_STREAM_END) { |
50 | 50 | fprintf(stderr, "Error while inflating buffer: %d - %s.\n", err,strm.msg); |
51 | 51 | inflateEnd(&strm); | ... | ... |