private void loadDefinition(Default317Buffer stream) { do { int opcode = stream.getUnsignedByte(); if (opcode == 0) { return; } else if (opcode == 1) { rgbColour = stream.get3Bytes(); rgbToHls(rgbColour); } else if (opcode == 2) { textureId = stream.getUnsignedByte(); } else if (opcode == 3) { } // dummy attribute else if (opcode == 5) { occlude = false; } else if (opcode == 6) { name = stream.getString(); } else if (opcode == 7) { int oldHue2 = hue2; int oldSat = saturation; int oldLight = lightness; int oldHue = hue; int rgb = stream.get3Bytes(); rgbToHls(rgb); hue2 = oldHue2; saturation = oldSat; lightness = oldLight; hue = oldHue; hueDivisor = oldHue; } else { throw new InvalidOperationException($"Error unrecognised config code: {opcode}"); } } while(true); }
public IndexedImage(Archive archive, String name, int id) { try { Default317Buffer imageBuffer = new Default317Buffer(archive.decompressFile(name + ".dat")); Default317Buffer metadataBuffer = new Default317Buffer(archive.decompressFile("index.dat")); metadataBuffer.position = imageBuffer.getUnsignedLEShort(); resizeWidth = metadataBuffer.getUnsignedLEShort(); resizeHeight = metadataBuffer.getUnsignedLEShort(); int colourCount = metadataBuffer.getUnsignedByte(); palette = new int[colourCount]; for (int c = 0; c < colourCount - 1; c++) { palette[c + 1] = metadataBuffer.get3Bytes(); } for (int i = 0; i < id; i++) { metadataBuffer.position += 2; imageBuffer.position += metadataBuffer.getUnsignedLEShort() * metadataBuffer.getUnsignedLEShort(); metadataBuffer.position++; } drawOffsetX = metadataBuffer.getUnsignedByte(); drawOffsetY = metadataBuffer.getUnsignedByte(); width = metadataBuffer.getUnsignedLEShort(); height = metadataBuffer.getUnsignedLEShort(); int type = metadataBuffer.getUnsignedByte(); int pixelCount = width * height; pixels = new byte[pixelCount]; if (type == 0) { for (int i = 0; i < pixelCount; i++) { pixels[i] = imageBuffer.get(); } return; } if (type == 1) { for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { pixels[x + y * width] = imageBuffer.get(); } } } } catch (Exception e) { throw new InvalidOperationException($"Failed to generate IndexedImage for: {name} id: {id}. Reason: {e.Message}\nStack: {e.StackTrace}", e); } }
public Archive(byte[] data) { Default317Buffer buffer = new Default317Buffer(data); int compressedLength = buffer.get3Bytes(); int decompressedLength = buffer.get3Bytes(); if (decompressedLength != compressedLength) { byte[] output = new byte[compressedLength]; Bzip2Decompressor.decompress(output, compressedLength, data, decompressedLength, 6); outputData = output; buffer = new Default317Buffer(outputData); this.decompressed = true; } else { outputData = data; this.decompressed = false; } fileCount = buffer.getUnsignedLEShort(); hashes = new int[fileCount]; decompressedSizes = new int[fileCount]; compressedSizes = new int[fileCount]; initialOffsets = new int[fileCount]; int offset = buffer.position + fileCount * 10; for (int index = 0; index < fileCount; index++) { hashes[index] = buffer.getInt(); decompressedSizes[index] = buffer.get3Bytes(); compressedSizes[index] = buffer.get3Bytes(); initialOffsets[index] = offset; offset += compressedSizes[index]; } }
public Sprite(Archive streamLoader, String target, int archiveId) { try { if (target.ToLower() == "headicons") { return; } Default317Buffer dataStream = new Default317Buffer(streamLoader.decompressFile(target + ".dat")); Default317Buffer indexStream = new Default317Buffer(streamLoader.decompressFile("index.dat")); indexStream.position = dataStream.getUnsignedLEShort(); maxWidth = indexStream.getUnsignedLEShort(); maxHeight = indexStream.getUnsignedLEShort(); int length = indexStream.getUnsignedByte(); int[] pixels = new int[length]; for (int p = 0; p < length - 1; p++) { pixels[p + 1] = indexStream.get3Bytes(); if (pixels[p + 1] == 0) { pixels[p + 1] = 1; } } for (int i = 0; i < archiveId; i++) { indexStream.position += 2; dataStream.position += indexStream.getUnsignedLEShort() * indexStream.getUnsignedLEShort(); indexStream.position++; } offsetX = indexStream.getUnsignedByte(); offsetY = indexStream.getUnsignedByte(); width = indexStream.getUnsignedLEShort(); height = indexStream.getUnsignedLEShort(); int type = indexStream.getUnsignedByte(); int pixelCount = width * height; this.pixels = new int[pixelCount]; if (type == 0) { for (int p = 0; p < pixelCount; p++) { this.pixels[p] = pixels[dataStream.getUnsignedByte()]; } return; } if (type == 1) { for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { this.pixels[x + y * width] = pixels[dataStream.getUnsignedByte()]; } } } } catch (Exception e) { isValid = false; //Don't throw, this is just a data error. Not an engine fault. throw new InvalidOperationException($"Failed to generate Sprite for: {target} id: {id}. Reason: {e.Message}\nStack: {e.StackTrace}", e); } }
public Sprite(Archive streamLoader, String target, int archiveId, Default317Buffer optionalIndexStream = null) { try { if (target.ToLower() == "headicons") { return; } Default317Buffer dataStream = new Default317Buffer(streamLoader.decompressFile(target + ".dat")); Default317Buffer indexStream = optionalIndexStream != null ? optionalIndexStream : new Default317Buffer(streamLoader.decompressFile("index.dat")); indexStream.position = dataStream.getUnsignedLEShort(); maxWidth = indexStream.getUnsignedLEShort(); maxHeight = indexStream.getUnsignedLEShort(); if (!IsDataAvailable(indexStream)) { InitializeAsEmpty(); return; } int length = indexStream.getUnsignedByte(); int[] pixels = new int[length]; for (int p = 0; p < length - 1; p++) { pixels[p + 1] = indexStream.get3Bytes(); if (pixels[p + 1] == 0) { pixels[p + 1] = 1; } } for (int i = 0; i < archiveId; i++) { indexStream.position += 2; dataStream.position += indexStream.getUnsignedLEShort() * indexStream.getUnsignedLEShort(); indexStream.position++; } if (!IsDataAvailable(indexStream)) { InitializeAsEmpty(); return; } offsetX = indexStream.getUnsignedByte(); if (!IsDataAvailable(indexStream)) { InitializeAsEmpty(); return; } offsetY = indexStream.getUnsignedByte(); width = indexStream.getUnsignedLEShort(); height = indexStream.getUnsignedLEShort(); if (!IsDataAvailable(indexStream)) { InitializeAsEmpty(); return; } int type = indexStream.getUnsignedByte(); int pixelCount = width * height; //Custom: Below are some sanity checks that are custom but help guard against known clean cache data issues. bool isEnoughDataAvailable = pixelCount <= (dataStream.buffer.Length - dataStream.position); //Don't let corrupt image data, in default cache, cause BIG allocation (bad for WebGL) //or allocate/read for empty images. if (pixelCount <= 0 || pixelCount > int.MaxValue / 100 || !isEnoughDataAvailable || dataStream.position < 0) //sometimes happens!! { width = 0; height = 0; this.pixels = Array.Empty <int>(); return; } this.pixels = new int[pixelCount]; try { if (type == 0) { for (int p = 0; p < pixelCount; p++) { this.pixels[p] = pixels[dataStream.getUnsignedByte()]; } return; } } catch (Exception e) { Console.WriteLine($"Failed to read image type: {type}. PixelCount: {pixelCount} StreamLength: {dataStream.buffer.Length} Position: {dataStream.position} Reason: {e}"); throw; } try { if (type == 1) { for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { this.pixels[x + y * width] = pixels[dataStream.getUnsignedByte()]; } } } } catch (Exception e) { Console.WriteLine($"Failed to read image type: {type}. PixelCount: {pixelCount} Reason: {e}"); throw; } } catch (Exception e) { isValid = false; //Don't throw, this is just a data error. Not an engine fault. throw new InvalidOperationException($"Failed to generate Sprite for: {target} id: {id}. Reason: {e.Message}\nStack: {e.StackTrace}", e); } }
public IndexedImage(Archive archive, String name, int id, Default317Buffer optionalMetaDataBuffer = null) { try { Default317Buffer imageBuffer = new Default317Buffer(archive.decompressFile(name + ".dat")); Default317Buffer metadataBuffer = optionalMetaDataBuffer != null ? optionalMetaDataBuffer : new Default317Buffer(archive.decompressFile("index.dat")); metadataBuffer.position = imageBuffer.getUnsignedLEShort(); resizeWidth = metadataBuffer.getUnsignedLEShort(); resizeHeight = metadataBuffer.getUnsignedLEShort(); int colourCount = metadataBuffer.getUnsignedByte(); palette = new int[colourCount]; for (int c = 0; c < colourCount - 1; c++) { palette[c + 1] = metadataBuffer.get3Bytes(); } for (int i = 0; i < id; i++) { metadataBuffer.position += 2; imageBuffer.position += metadataBuffer.getUnsignedLEShort() * metadataBuffer.getUnsignedLEShort(); metadataBuffer.position++; } drawOffsetX = metadataBuffer.getUnsignedByte(); drawOffsetY = metadataBuffer.getUnsignedByte(); width = metadataBuffer.getUnsignedLEShort(); height = metadataBuffer.getUnsignedLEShort(); int type = metadataBuffer.getUnsignedByte(); int pixelCount = width * height; //Custom: Below are some sanity checks that are custom but help guard against known clean cache data issues. bool isEnoughDataAvailable = pixelCount <= (imageBuffer.buffer.Length - imageBuffer.position); //Don't let corrupt image data, in default cache, cause BIG allocation (bad for WebGL) //or allocate/read for empty images. if (pixelCount <= 0 || pixelCount > int.MaxValue / 100 || !isEnoughDataAvailable || imageBuffer.position < 0) //sometimes happens!! { width = 0; height = 0; this.pixels = Array.Empty <byte>(); return; } pixels = new byte[pixelCount]; if (type == 0) { for (int i = 0; i < pixelCount; i++) { pixels[i] = imageBuffer.get(); } return; } if (type == 1) { for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { pixels[x + y * width] = imageBuffer.get(); } } } } catch (Exception e) { isValid = false; //Don't throw, this is just a data error. Not an engine fault. throw new InvalidOperationException($"Failed to generate IndexedImage for: {name} id: {id}. Reason: {e.Message}\nStack: {e.StackTrace}", e); } }