Fix a 0 byte file getting loaded as a 1x1x1 map

This commit is contained in:
UnknownShadow200 2018-11-15 19:48:27 +11:00
parent eeced2364b
commit ea7fac097d
5 changed files with 23 additions and 14 deletions

View File

@ -59,8 +59,9 @@ namespace MCGalaxy.Levels.IO {
int length = BitConverter.ToInt32(temp, 0);
byte[] data = new byte[length];
using (GZipStream reader = new GZipStream(src, CompressionMode.Decompress, true))
using (GZipStream reader = new GZipStream(src, CompressionMode.Decompress, true)) {
reader.Read(data, 0, length);
}
for (int i = 0; i < length - 1; i++) {
if (data[i] != MAGIC1 || data[i + 1] != MAGIC2) continue;

View File

@ -63,7 +63,7 @@ namespace MCGalaxy.Levels.IO {
Logger.LogError("Error importing zone '" + key + "' from fCraft map", ex);
}
}
int read = ds.Read(lvl.blocks, 0, lvl.blocks.Length);
ReadFully(ds, lvl.blocks, lvl.blocks.Length);
}
ConvertCustom(lvl);
return lvl;

View File

@ -51,7 +51,7 @@ namespace MCGalaxy.Levels.IO {
lvl.rotx = header[offset + 10];
lvl.roty = header[offset + 11];
gs.Read(lvl.blocks, 0, lvl.blocks.Length);
ReadFully(gs, lvl.blocks, lvl.blocks.Length);
ReadCustomBlocksSection(lvl, gs);
if (!metadata) return lvl;
@ -69,16 +69,16 @@ namespace MCGalaxy.Levels.IO {
}
static Vec3U16 ReadHeader(Stream gs, byte[] header, out int offset) {
gs.Read(header, 0, 2);
ReadFully(gs, header, 2);
Vec3U16 dims = default(Vec3U16);
dims.X = BitConverter.ToUInt16(header, 0);
if (dims.X == 1874) { // version field, width is next ushort
gs.Read(header, 0, 16);
ReadFully(gs, header, 16);
dims.X = BitConverter.ToUInt16(header, 0);
offset = 2;
} else {
gs.Read(header, 0, 12);
ReadFully(gs, header, 12);
offset = 0;
}
@ -100,7 +100,7 @@ namespace MCGalaxy.Levels.IO {
read = gs.Read(data, 0, 1);
if (read > 0 && data[0] == 1) {
byte[] chunk = new byte[16 * 16 * 16];
gs.Read(chunk, 0, chunk.Length);
ReadFully(gs, chunk, chunk.Length);
lvl.CustomBlocks[index] = chunk;
}
index++;
@ -130,7 +130,7 @@ namespace MCGalaxy.Levels.IO {
int* ptrInt = (int*)ptr;
for (int j = 0; j < entries; j++) {
C.Index = *ptrInt; ptrInt++;
C.Index = *ptrInt; ptrInt++;
C.data.Raw = (uint)(*ptrInt); ptrInt++;
lvl.ListCheck.Items[i + j] = C;
}
@ -163,7 +163,7 @@ namespace MCGalaxy.Levels.IO {
for (int j = 0; j < metaCount; j++) {
int size = Read_U16(buffer, gs);
if (size > buffer.Length) buffer = new byte[size + 16];
gs.Read(buffer, 0, size);
ReadFully(gs, buffer, size);
string line = Encoding.UTF8.GetString(buffer, 0, size), key, value;
PropertiesFile.ParseLine(line, '=', out key, out value);
@ -182,9 +182,7 @@ namespace MCGalaxy.Levels.IO {
}
static ushort Read_U16(byte[] buffer, Stream gs) {
int read = gs.Read(buffer, 0, sizeof(ushort));
if (read < sizeof(ushort)) throw new EndOfStreamException("End of stream reading U16");
ReadFully(gs, buffer, sizeof(ushort));
return NetUtils.ReadU16(buffer, 0);
}
}

View File

@ -58,11 +58,11 @@ namespace MCGalaxy.Levels.IO {
}
static Vec3U16 ReadHeader(byte[] header, Stream gs) {
gs.Read(header, 0, 2);
ReadFully(gs, header, 2);
if (BitConverter.ToUInt16(header, 0) != 1874)
throw new InvalidDataException(".mcf files must have a version of 1874");
gs.Read(header, 0, 16);
ReadFully(gs, header, 16);
Vec3U16 dims;
dims.X = BitConverter.ToUInt16(header, 0);
dims.Z = BitConverter.ToUInt16(header, 2);

View File

@ -67,6 +67,16 @@ namespace MCGalaxy.Levels.IO {
lvl.FastSetExtTile(x, y, z, raw);
}
}
protected static void ReadFully(Stream s, byte[] data, int count) {
int offset = 0;
while (count > 0) {
int read = s.Read(data, offset, count);
if (read == 0) throw new EndOfStreamException("End of stream reading data");
offset += read; count -= read;
}
}
}
/// <summary> Writes/Saves block data (and potentially metadata) encoded in a particular format. </summary>