mirror of
https://github.com/2006-Scape/2006RebottedClient.git
synced 2026-07-02 16:49:02 +00:00
102 lines
2.5 KiB
Java
102 lines
2.5 KiB
Java
package org.rebotted.cache;
|
|
|
|
import org.rebotted.cache.bzip.BZip2Decompressor;
|
|
import org.rebotted.io.Buffer;
|
|
|
|
public final class FileArchive {
|
|
|
|
/**
|
|
* The buffer containing the decompressed data in this Archive.
|
|
*/
|
|
private final byte[] buffer;
|
|
|
|
/**
|
|
* The amount of entries in this Archive.
|
|
*/
|
|
private final int entries;
|
|
|
|
/**
|
|
* The identifiers (i.e. hashed names) of each of the entries in this Archive.
|
|
*/
|
|
private final int[] identifiers;
|
|
|
|
/**
|
|
* The raw (i.e. decompressed) sizes of each of the entries in this Archive.
|
|
*/
|
|
private final int[] extractedSizes;
|
|
|
|
/**
|
|
* The compressed sizes of each of the entries in this Archive.
|
|
*/
|
|
private final int[] sizes;
|
|
private final int[] indices;
|
|
|
|
/**
|
|
* Whether or not this Archive was compressed as a whole: if false, decompression will be performed on each of the
|
|
* individual entries.
|
|
*/
|
|
private final boolean extracted;
|
|
|
|
public FileArchive(byte data[]) {
|
|
Buffer buffer = new Buffer(data);
|
|
|
|
int decompressedLength = buffer.readTriByte();
|
|
int compressedLength = buffer.readTriByte();
|
|
|
|
if (compressedLength != decompressedLength) {
|
|
|
|
byte output[] = new byte[decompressedLength];
|
|
|
|
BZip2Decompressor.decompress(output, decompressedLength, data, compressedLength, 6);
|
|
|
|
this.buffer = output;
|
|
|
|
buffer = new Buffer(this.buffer);
|
|
extracted = true;
|
|
} else {
|
|
this.buffer = data;
|
|
extracted = false;
|
|
}
|
|
entries = buffer.readUShort();
|
|
identifiers = new int[entries];
|
|
extractedSizes = new int[entries];
|
|
sizes = new int[entries];
|
|
indices = new int[entries];
|
|
int offset = buffer.currentPosition + entries * 10;
|
|
for (int file = 0; file < entries; file++) {
|
|
identifiers[file] = buffer.readInt();
|
|
extractedSizes[file] = buffer.readTriByte();
|
|
sizes[file] = buffer.readTriByte();
|
|
indices[file] = offset;
|
|
offset += sizes[file];
|
|
}
|
|
}
|
|
|
|
public byte[] readFile(String name) {
|
|
byte output[] = null;
|
|
int hash = 0;
|
|
name = name.toUpperCase();
|
|
for (int index = 0; index < name.length(); index++) {
|
|
hash = (hash * 61 + name.charAt(index)) - 32;
|
|
}
|
|
|
|
for (int file = 0; file < entries; file++) {
|
|
if (identifiers[file] == hash) {
|
|
if (output == null) {
|
|
output = new byte[extractedSizes[file]];
|
|
}
|
|
if (!extracted) {
|
|
BZip2Decompressor.decompress(output, extractedSizes[file], this.buffer,
|
|
sizes[file], indices[file]);
|
|
} else {
|
|
System.arraycopy(this.buffer, indices[file], output,
|
|
0, extractedSizes[file]);
|
|
}
|
|
return output;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
}
|