package tk.captainsplexx.Resource.CAS; import java.io.File; import java.nio.ByteOrder; import java.util.ArrayList; import java.util.Random; import tk.captainsplexx.Maths.Hash; import tk.captainsplexx.Resource.FileHandler; public class CasManager { static byte[] header = new byte[] { (byte) 0xFA, (byte) 0xCE, (byte) 0x0F, (byte) 0xF0, (byte) 0x5F, (byte) 0x5F, (byte) 0x5F, (byte) 0x53, (byte) 0x50, (byte) 0x4C, (byte) 0x45, (byte) 0x58, (byte) 0x58, (byte) 0x5F, (byte) 0x5F, (byte) 0x5F}; static byte[] compressionType = new byte[] {(byte) 0x00, (byte) 0x70}; static int blockSize = 0x10000; static int blockContent = 0xFAD8&0xFFFF; public static int blockHeaderNumBytes = 8;//4 size, 2 type, 2 compressed size public static boolean createCAS(String path99cas){ try{ File casFile = new File(FileHandler.normalizePath(path99cas)); if (casFile.exists()){ System.err.println("Cas file does already exist."); return false; } if (FileHandler.writeFile(path99cas, header)){ return true; } return false; }catch (Exception e){ System.err.println("Could not create a new CAS file! "+path99cas); return false; } } public static CasCatEntry extendCAS(byte[] decompressedBytes, File cas, CasCatManager casCatMan){ if (!cas.exists()){return null;} System.err.println("CasManager is extending the CAS using a custom max. block size\n"+ "we should change it to the default and set each block compressed size to 0x0!"); ArrayList<Byte> procEntries = new ArrayList<Byte>(); /*HANDLE BLOCK LOGIC*/ int blocks = calculateNumberOfBlocks(decompressedBytes.length); //System.out.println(blockContent); System.out.println("Building "+(blocks+1)+" blocks in total."); int restLen = decompressedBytes.length - (blocks * blockContent); for (int i=0; i<blocks; i++){ FileHandler.addBytes(FileHandler.toBytes(blockSize, ByteOrder.BIG_ENDIAN), procEntries);//int FileHandler.addBytes(compressionType, procEntries); FileHandler.addBytes(FileHandler.toBytes((short) (blockContent&0xFFFF), ByteOrder.BIG_ENDIAN), procEntries);/*short -- this can may be even 0x00, because FrankElster said: "..compressed size (null for type 0071 and type 0000) of the payload .. without the header"*/ FileHandler.addBytes(decompressedBytes, procEntries, i*blockContent, blockContent); } /*FILL REST*/ FileHandler.addBytes(FileHandler.toBytes(restLen, ByteOrder.BIG_ENDIAN), procEntries); FileHandler.addBytes(compressionType, procEntries); // 0x0070 -- uncompressed || 0x0970 lz4 compressed || 0x0071 -- uncompressed no payload || 0x0000 -- empty payload FileHandler.addBytes(FileHandler.toBytes((short) restLen, ByteOrder.BIG_ENDIAN), procEntries); FileHandler.addBytes(decompressedBytes, procEntries, blocks*blockContent, restLen); /*EXTEND AND RETURN NEW ENTRY!*/ int casEntryOffset = (int) cas.length(); //Max file size is anyways less than 2GB's so we can go with integers. if (FileHandler.writeFile(FileHandler.normalizePath(cas.getAbsolutePath()), FileHandler.toByteArray(procEntries), true)){ CasCatEntry entry = new CasCatEntry(genSHA1(casCatMan), casEntryOffset, procEntries.size(), 99); System.out.println("New CatCatEntry "+entry.getSHA1()+" in cas_99 created!"); return entry; } System.err.println("Could not extend CASFile :("); return null; } static String genSHA1(CasCatManager casCatMan){ Random random = new Random(); String sha1 = Hash.getSHA1(random.nextInt(1231222223)+random.nextInt(1231222223)+"SPLEXX"); for (CasCatEntry entry : casCatMan.getEntries()){ if (entry.getSHA1().equalsIgnoreCase(sha1)){ return genSHA1(casCatMan); } } return sha1; } public static int calculateNumberOfBlocks(int rawLength){ return rawLength / blockContent; } }