Code: Alles auswählen
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.util.zip.InflaterInputStream;
public class UOKRDecomp {
public static void main(String[] args) {
try {
File inputFile = new File(args[0]);
RandomAccessFile raf = new RandomAccessFile(inputFile, "r");
byte[] generalFormatHeader = new byte[40];
raf.readFully(generalFormatHeader);
boolean moreIndexes = true;
int indexNumber = 0;
while (moreIndexes) {
int indexFileNumber = Integer.reverseBytes(raf.readInt());
long nextIndexBlockOffset = Long.reverseBytes(raf.readLong());
long dataBlockOffset = Long.reverseBytes(raf.readLong());
System.out.println("Number of index files: " + indexFileNumber);
System.out.println("Next index block offset: " + nextIndexBlockOffset);
System.out.println("Next data block offset: " + dataBlockOffset);
raf.skipBytes(4);
int[] compressedDataLength = new int[indexFileNumber+1];
for (int i = 0; i < indexFileNumber; i++) {
compressedDataLength[i] = Integer.reverseBytes(raf.readInt());
int decompressedDataLength = Integer.reverseBytes(raf.readInt());
System.out.println("Length of compressed data: " + compressedDataLength[1]);
System.out.println("Length of decompressed data: " + decompressedDataLength);
raf.skipBytes(26);
}
raf.seek(dataBlockOffset);
raf.skipBytes(12);
for (int i = 0; i < indexFileNumber; i++) {
FileInputStream fis = new FileInputStream(inputFile);
fis.skip(raf.getFilePointer());
InflaterInputStream iis = new InflaterInputStream(fis);
int bytesRead = 0;
byte[] byteBuffer = new byte[4096];
File outputFile = new File(inputFile.getAbsolutePath() + ".dir");
if (!outputFile.exists())
outputFile.mkdir();
outputFile = new File(inputFile.getAbsolutePath() + ".dir\\" + inputFile.getName() + "."
+ indexNumber + "." + i);
System.out.println("Decompressing to " + outputFile.getName());
FileOutputStream fos = new FileOutputStream(outputFile);
int bytesRetrieved = 0;
while ((bytesRead < compressedDataLength[i]) && (bytesRetrieved != -1)) {
bytesRetrieved = iis.read(byteBuffer);
if (bytesRetrieved != -1) {
bytesRead += bytesRetrieved;
fos.write(byteBuffer, 0, bytesRetrieved);
}
}
fos.close();
System.out.println("Decompressing done.");
}
if (nextIndexBlockOffset == 0)
moreIndexes = false;
else {
raf.seek(nextIndexBlockOffset);
indexNumber++;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Bsp. wenn ihr den Code im UO:KR Verzeichnis anlegt:
Code: Alles auswählen
F:\Games\UOKR>javac UOKRDecomp.java
F:\Games\UOKR>java UOKRDecomp MainMisc.uop
Number of index files: 3
Next index block offset: 0
Next data block offset: 3452
Length of compressed data: 0
Length of decompressed data: 3915
Length of compressed data: 43126
Length of decompressed data: 193668
Length of compressed data: 43126
Length of decompressed data: 2311
Decompressing to MainMisc.uop.0.0
Decompressing done.
Decompressing to MainMisc.uop.0.1
Decompressing done.
Decompressing to MainMisc.uop.0.2
Decompressing done.
F:\Games\UOKR>
Das ganze basiert auf der UOP Fileformat ( aka Mythic Package ) Dokumentation von - Kelon & SENE - (kenne die beiden nicht direkt, aber sie sind in der Doku erwähnt). Das Programm ist einfach nur ohne viel Stil runtergeschrieben und wird nicht weiterentwickelt, aber vielleicht kann ja jemand etwas damit anfangen.
Gruß
Nerzul