package tk.captainsplexx.Resource.TOC; import java.nio.ByteOrder; import java.util.ArrayList; import tk.captainsplexx.Game.Core; import tk.captainsplexx.Resource.FileHandler; import tk.captainsplexx.Resource.ResourceHandler.LinkBundleType; import tk.captainsplexx.Resource.ResourceHandler.ResourceType; import tk.captainsplexx.Resource.CAS.CasDataReader; import tk.captainsplexx.Resource.EBX.EBXLoader; import tk.captainsplexx.Resource.TOC.TocManager.TocFieldType; public class TocConverter { public static enum ResourceBundleType{EBX, DBX, RES, CHUNKS, CHUNKMETA}; @SuppressWarnings("unchecked") public static ConvertedTocFile convertTocFile(TocFile toc){ //FOR TOC ONLY -> NOT SBPART <- try{ ConvertedTocFile convToc = new ConvertedTocFile(/*USING NULLCONSTUCTOR*/); TocEntry masterEntry = toc.getEntries().get(0); for (TocField field : masterEntry.getFields()){ if (field.getName().toLowerCase().equals("alwaysemitsuperbundle") && field.getType() == TocFieldType.BOOL){ convToc.setAlwaysEmitSuperBundle((boolean) field.getObj()); }else if (field.getName().toLowerCase().equals("cas") && field.getType() == TocFieldType.BOOL){ convToc.setCas((boolean) field.getObj()); }else if (field.getName().toLowerCase().equals("name") && field.getType() == TocFieldType.STRING){ //no name in update folder! convToc.setName((String)field.getObj()); }else if (field.getName().toLowerCase().equals("chunks") && field.getType() == TocFieldType.LIST){ for (TocEntry entry : (ArrayList<TocEntry>) field.getObj()){ TocSBLink link = readTocLink(entry, toc.getSBPath()); if (link != null){ link.setType(LinkBundleType.CHUNKS); convToc.getChunks().add(link); } } }else if (field.getName().toLowerCase().equals("bundles") && field.getType() == TocFieldType.LIST){ for (TocEntry entry : (ArrayList<TocEntry>) field.getObj()){ TocSBLink link = readTocLink(entry, toc.getSBPath()); if (link != null){ link.setType(LinkBundleType.BUNDLES); convToc.getBundles().add(link); } } }else if (field.getName().toLowerCase().equals("tag") && field.getType() == TocFieldType.GUID){ convToc.setTag((String)field.getObj()); }else if (field.getName().toLowerCase().equals("totalsize") && field.getType() == TocFieldType.LONG){ convToc.setTotalSize((Long)field.getObj()); }else{ System.err.println("unexpected field found in toc file while converting: "+field.getName()+" as type: "+field.getType()); } } return convToc; }catch (Exception e){ //e.printStackTrace(); System.err.println("Could not convert TocFile!"); return null; } } static TocSBLink readTocLink(TocEntry entry, String pathSb){ TocSBLink link = new TocSBLink(/*USING NULLCONSTUCTOR*/); if (entry != null){ for (TocField field : entry.getFields()){ if (field.getName().toLowerCase().equals("id") && field.getType() == TocFieldType.STRING){ link.setID((String) field.getObj()); }else if (field.getName().toLowerCase().equals("id") && field.getType() == TocFieldType.GUID){ link.setGuid((String) field.getObj()); }else if (field.getName().toLowerCase().equals("sha1") && field.getType() == TocFieldType.SHA1){ link.setSha1((String) field.getObj()); }else if (field.getName().toLowerCase().equals("offset") && field.getType() == TocFieldType.LONG){ link.setOffset((long) field.getObj()); }else if (field.getName().toLowerCase().equals("size") && field.getType() == TocFieldType.INTEGER){ link.setSize((int) field.getObj()); }else if (field.getName().toLowerCase().equals("size") && field.getType() == TocFieldType.LONG){ link.setSizeLong((long) field.getObj()); }else if (field.getName().toLowerCase().equals("delta") && field.getType() == TocFieldType.BOOL){ link.setDelta((boolean) field.getObj()); }else if (field.getName().toLowerCase().equals("base") && field.getType() == TocFieldType.BOOL){ link.setBase((boolean) field.getObj()); }else{ System.err.println("unexpected field (link) found in toc file while converting: "+field.getName()+" as type "+field.getType()); } } link.setSbPath(FileHandler.normalizePath(pathSb)); return link; }else{ return null; } } @SuppressWarnings("unchecked") public static ConvertedSBpart convertSBpart(TocFile sbpart){ try{ ConvertedSBpart convSB = new ConvertedSBpart(/*USING NULLCONSTRUCTOR*/); TocEntry masterEntry = sbpart.getEntries().get(0); for (TocField field : masterEntry.getFields()){ if (field.getName().toLowerCase().equals("path") && field.getType() == TocFieldType.STRING){ convSB.setPath((String) field.getObj()); }else if (field.getName().toLowerCase().equals("magicsalt") && field.getType() == TocFieldType.INTEGER){ convSB.setMagicSalt((Integer) field.getObj()); }else if (field.getName().toLowerCase().equals("alignmembers") && field.getType() == TocFieldType.BOOL){ convSB.setAlignMembers((Boolean) field.getObj()); }else if (field.getName().toLowerCase().equals("ridsupport") && field.getType() == TocFieldType.BOOL){ convSB.setRidSupport((Boolean) field.getObj()); }else if (field.getName().toLowerCase().equals("storecompressedsizes") && field.getType() == TocFieldType.BOOL){ convSB.setStoreCompressedSizes((Boolean) field.getObj()); }else if (field.getName().toLowerCase().equals("totalsize") && field.getType() == TocFieldType.LONG){ convSB.setTotalSize((long) field.getObj()); }else if (field.getName().toLowerCase().equals("dbxtotalsize") && field.getType() == TocFieldType.LONG){ convSB.setDbxTotalSize((long) field.getObj()); } else if (field.getName().toLowerCase().equals("ebx") && field.getType() == TocFieldType.LIST){ for (TocEntry entry : (ArrayList<TocEntry>) field.getObj()){ ResourceLink link = readResourceLink(entry, ResourceBundleType.EBX); if (link != null){ convSB.getEbx().add(link); } } }else if (field.getName().toLowerCase().equals("dbx") && field.getType() == TocFieldType.LIST){ for (TocEntry entry : (ArrayList<TocEntry>) field.getObj()){ ResourceLink link = readResourceLink(entry, ResourceBundleType.DBX); if (link != null){ convSB.getDbx().add(link); } } }else if (field.getName().toLowerCase().equals("res") && field.getType() == TocFieldType.LIST){ for (TocEntry entry : (ArrayList<TocEntry>) field.getObj()){ ResourceLink link = readResourceLink(entry, ResourceBundleType.RES); if (link != null){ convSB.getRes().add(link); } } }else if (field.getName().toLowerCase().equals("chunks") && field.getType() == TocFieldType.LIST){ for (TocEntry entry : (ArrayList<TocEntry>) field.getObj()){ ResourceLink link = readResourceLink(entry, ResourceBundleType.CHUNKS); if (link != null){ convSB.getChunks().add(link); } } }else if (field.getName().toLowerCase().equals("chunkmeta") && field.getType() == TocFieldType.LIST){ //chunk(only singular)Meta! for (TocEntry entry : (ArrayList<TocEntry>) field.getObj()){ ResourceLink link = readResourceLink(entry, ResourceBundleType.CHUNKMETA); if (link != null){ convSB.getChunkMeta().add(link); } } }else{ System.err.println("TocConverter found an unhandled field: "+field.getName()+" as "+field.getType()); } } return convSB; }catch (Exception e){ //e.printStackTrace(); System.err.println("Could not convert SBpart! ("+e.getCause()+")"); return null; } } static ResourceLink readResourceLink(TocEntry entry, ResourceBundleType type) { if (entry != null){ ResourceLink link = new ResourceLink(/*USING NULLCONSTUCTOR*/); link.setBundleType(type); //type-specific switch(type){ case CHUNKS: for (TocField field : entry.getFields()){ if (field.getName().toLowerCase().equals("sha1") && field.getType() == TocFieldType.SHA1){ link.setSha1((String) field.getObj()); }else if (field.getName().toLowerCase().equals("sha1") && field.getType() == TocFieldType.STRING){ link.setSha1((String) field.getObj()); }else if (field.getName().toLowerCase().equals("id") && field.getType() == TocFieldType.GUID){ link.setId((String) field.getObj()); }else if (field.getName().toLowerCase().equals("size") && field.getType() == TocFieldType.LONG){ link.setSize((Long) field.getObj()); }else if (field.getName().toLowerCase().equals("logicaloffset") && field.getType() == TocFieldType.INTEGER){ link.setLogicalOffset((Integer) field.getObj()); }else if (field.getName().toLowerCase().equals("logicalsize") && field.getType() == TocFieldType.INTEGER){ link.setLogicalSize((Integer) field.getObj()); }else if (field.getName().toLowerCase().equals("rangestart") && field.getType() == TocFieldType.INTEGER){ link.setRangeStart((Integer) field.getObj()); }else if (field.getName().toLowerCase().equals("rangeend") && field.getType() == TocFieldType.INTEGER){ link.setRangeEnd((Integer) field.getObj()); }else if (field.getName().toLowerCase().equals("caspatchtype") && field.getType() == TocFieldType.INTEGER){ link.setCasPatchType((Integer) field.getObj()); }else if (field.getName().toLowerCase().equals("basesha1") && field.getType() == TocFieldType.SHA1){ link.setBaseSha1((String) field.getObj()); }else if (field.getName().toLowerCase().equals("deltasha1") && field.getType() == TocFieldType.SHA1){ link.setDeltaSha1((String) field.getObj()); }else{ typeNotHandled(field); } link.setType(ResourceType.CHUNK); } Core.getGame().getChunkGUIDSHA1().put(link.getId().toLowerCase(), link.getSha1()); break; case CHUNKMETA: for (TocField field : entry.getFields()){ if (field.getName().toLowerCase().equals("h32") && field.getType() == TocFieldType.INTEGER){ link.setH32((Integer) field.getObj()); }else if (field.getName().toLowerCase().equals("meta") && field.getType() == TocFieldType.RAW){ link.setMeta((byte[]) field.getObj()); }else if (field.getName().toLowerCase().equals("firstmip") && field.getType() == TocFieldType.INTEGER){ link.setFirstMip((Integer) field.getObj()); }else if (field.getName().toLowerCase().equals("caspatchtype") && field.getType() == TocFieldType.INTEGER){ link.setCasPatchType((Integer) field.getObj()); }else if (field.getName().toLowerCase().equals("basesha1") && field.getType() == TocFieldType.SHA1){ link.setBaseSha1((String) field.getObj()); }else if (field.getName().toLowerCase().equals("deltasha1") && field.getType() == TocFieldType.SHA1){ link.setDeltaSha1((String) field.getObj()); }else{ typeNotHandled(field); } } break; case DBX: for (TocField field : entry.getFields()){ if (field.getName().toLowerCase().equals("name") && field.getType() == TocFieldType.STRING){ link.setName((String) field.getObj()); }else if (field.getName().toLowerCase().equals("sha1") && field.getType() == TocFieldType.SHA1){ link.setSha1((String) field.getObj()); }else if (field.getName().toLowerCase().equals("size") && field.getType() == TocFieldType.LONG){ link.setSize((Long) field.getObj()); }else if (field.getName().toLowerCase().equals("originalsize") && field.getType() == TocFieldType.LONG){ link.setOriginalSize((Long) field.getObj()); }else if (field.getName().toLowerCase().equals("caspatchtype") && field.getType() == TocFieldType.INTEGER){ link.setCasPatchType((Integer) field.getObj()); }else if (field.getName().toLowerCase().equals("basesha1") && field.getType() == TocFieldType.SHA1){ link.setBaseSha1((String) field.getObj()); }else if (field.getName().toLowerCase().equals("deltasha1") && field.getType() == TocFieldType.SHA1){ link.setDeltaSha1((String) field.getObj()); }else{ typeNotHandled(field); } } break; case EBX: for (TocField field : entry.getFields()){ if (field.getName().toLowerCase().equals("name") && field.getType() == TocFieldType.STRING){ link.setName((String) field.getObj()); }else if (field.getName().toLowerCase().equals("sha1") && field.getType() == TocFieldType.SHA1){ link.setSha1((String) field.getObj()); }else if (field.getName().toLowerCase().equals("size") && field.getType() == TocFieldType.LONG){ link.setSize((Long) field.getObj()); }else if (field.getName().toLowerCase().equals("originalsize") && field.getType() == TocFieldType.LONG){ link.setOriginalSize((Long) field.getObj()); }else if (field.getName().toLowerCase().equals("caspatchtype") && field.getType() == TocFieldType.INTEGER){ link.setCasPatchType((Integer) field.getObj()); }else if (field.getName().toLowerCase().equals("basesha1") && field.getType() == TocFieldType.SHA1){ link.setBaseSha1((String) field.getObj()); }else if (field.getName().toLowerCase().equals("deltasha1") && field.getType() == TocFieldType.SHA1){ link.setDeltaSha1((String) field.getObj()); }else{ typeNotHandled(field); } link.setType(ResourceType.EBX); } try{ link.setEbxFileGUID( EBXLoader.getGUID( CasDataReader.readCas( link.getBaseSha1(), link.getDeltaSha1(), link.getSha1(), link.getCasPatchType() ) ) ); }catch (Exception e){ e.printStackTrace(); //Timeout in JavaFX Thread ?? } break; case RES: for (TocField field : entry.getFields()){ if (field.getName().toLowerCase().equals("name") && field.getType() == TocFieldType.STRING){ link.setName((String) field.getObj()); }else if (field.getName().toLowerCase().equals("sha1") && field.getType() == TocFieldType.SHA1){ link.setSha1((String) field.getObj()); }else if (field.getName().toLowerCase().equals("size") && field.getType() == TocFieldType.LONG){ link.setSize((Long) field.getObj()); }else if (field.getName().toLowerCase().equals("originalsize") && field.getType() == TocFieldType.LONG){ link.setOriginalSize((Long) field.getObj()); }else if (field.getName().toLowerCase().equals("restype") && field.getType() == TocFieldType.INTEGER){ int resType = (Integer) field.getObj(); link.setType(toResourceType(resType)); link.setResType(resType); }else if (field.getName().toLowerCase().equals("resmeta") && field.getType() == TocFieldType.RAW2){ link.setResMeta((byte[]) field.getObj()); }else if (field.getName().toLowerCase().equals("resrid") && field.getType() == TocFieldType.LONG){ link.setResRid((long) field.getObj()); }else if (field.getName().toLowerCase().equals("idata") && field.getType() == TocFieldType.RAW2){ link.setIdata((byte[]) field.getObj()); }else if (field.getName().toLowerCase().equals("caspatchtype") && field.getType() == TocFieldType.INTEGER){ link.setCasPatchType((Integer) field.getObj()); }else if (field.getName().toLowerCase().equals("basesha1") && field.getType() == TocFieldType.SHA1){ link.setBaseSha1((String) field.getObj()); }else if (field.getName().toLowerCase().equals("deltasha1") && field.getType() == TocFieldType.SHA1){ link.setDeltaSha1((String) field.getObj()); }else{ typeNotHandled(field); } } break; } return link; }else{ return null; } } public static void typeNotHandled(TocField entry){ System.err.println("TocConverter found a not handled Field. Type: "+entry.getType()+" Name: "+entry.getName()); } public static ResourceType toResourceType(int resType){ switch(resType){ case 0x5C4954A6: return ResourceType.ITEXTURE; case 0x2D47A5FF: return ResourceType.GFX; case 0x22FE8AC8: return ResourceType.UNDEFINED; case 0x6BB6D7D2: return ResourceType.STREAIMINGSTUB; case 0x1CA38E06: return ResourceType.UNDEFINED; case 0x15E1F32E: return ResourceType.UNDEFINED; case 0x4864737B: return ResourceType.HKDESTRUCTION; case 0x91043F65: return ResourceType.HKNONDESTRUCTION; case 0x51A3C853: return ResourceType.ANT; case 0xD070EED1: return ResourceType.ANIMTRACKDATA; case 0x319D8CD0: return ResourceType.RAGDOLL; case 0x30B4A553: return ResourceType.OCCLUSIONMESH; case 0x49B156D4: return ResourceType.MESH; case 0x5BDFDEFE: return ResourceType.LIGHTINGSYSTEM; case 0x70C5CB3E: return ResourceType.ENLIGHTEN; case 0xE156AF73: return ResourceType.PROBESET; case 0x7AEFC446: return ResourceType.STATICENLIGHTEN; case 0x59CEEB57: return ResourceType.SHADERDATERBASE; case 0x36F3F2C0: return ResourceType.SHADERDB; case 0x10F0E5A1: return ResourceType.SHADERPROGRAMDB; case 0xafecb022: return ResourceType.LUAC; case 0x957C32B1: return ResourceType.UNDEFINED; case 0xC6CD3286: return ResourceType.UNDEFINED; case 0xA23E75DB: return ResourceType.UNDEFINED; default: System.out.println("unknown ResourceType found in TocConverter: "+FileHandler.toHexInteger((resType&0xFFFFFFFF), ByteOrder.BIG_ENDIAN)); return ResourceType.UNDEFINED; } } }