package konogonka.Tools.PFS0; import konogonka.RainbowHexDump; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.charset.StandardCharsets; import java.util.Arrays; import static konogonka.LoperConverter.*; public class PFS0Provider { private long pfs0offsetPosition; private long rawFileDataStart; private String magic; private int filesCount; private int stringTableSize; private byte[] padding; private PFS0subFile[] pfs0subFiles; public PFS0Provider(File fileWithPfs0) throws Exception{ this(fileWithPfs0, 0); } public PFS0Provider(File fileWithPfs0, long pfs0offsetPosition) throws Exception{ this.pfs0offsetPosition = pfs0offsetPosition; try { RandomAccessFile raf = new RandomAccessFile(fileWithPfs0, "r"); raf.seek(pfs0offsetPosition); byte[] fileStartingBytes = new byte[0x10]; // Read PFS0Provider, files count, header, padding (4 zero bytes) if (raf.read(fileStartingBytes) != 0x10){ raf.close(); throw new Exception("PFS0Provider: Unable to read starting bytes"); } // Check PFS0Provider magic = new String(fileStartingBytes, 0x0, 0x4, StandardCharsets.US_ASCII); if (! magic.equals("PFS0")){ raf.close(); throw new Exception("PFS0Provider: Bad magic"); } // Get files count filesCount = getLEint(fileStartingBytes, 0x4); if (filesCount <= 0 ) { raf.close(); throw new Exception("PFS0Provider: Files count is too small"); } // Get string table stringTableSize = getLEint(fileStartingBytes, 0x8); if (stringTableSize <= 0 ){ raf.close(); throw new Exception("PFS0Provider: String table is too small"); } padding = Arrays.copyOfRange(fileStartingBytes, 0xc, 0x10); //--------------------------------------------------------------------------------------------------------- pfs0subFiles = new PFS0subFile[filesCount]; long[] offsetsSubFiles = new long[filesCount]; long[] sizesSubFiles = new long[filesCount]; int[] strTableOffsets = new int[filesCount]; byte[][] zeroBytes = new byte[filesCount][]; byte[] fileEntryTable = new byte[0x18]; for (int i=0; i