Ejemplo n.º 1
0
        public static AssetsReplacer CreatePreloadData(ulong pathId)
        {
            byte[] metaAsset = null;
            using (MemoryStream ms = new MemoryStream())
                using (AssetsFileWriter writer = new AssetsFileWriter(ms))
                {
                    writer.bigEndian = false;

                    writer.Write(0);
                    writer.Align();

                    //writer.Write(gameObjects.Count);
                    //
                    //foreach (AssetID gameObject in gameObjects)
                    //{
                    //    writer.Write(gameObject.fileId);
                    //    writer.Write(gameObject.pathId);
                    //}
                    writer.Write(1);

                    writer.Write(1);
                    writer.Write((long)10001);
                    writer.Align();

                    writer.Write(0);
                    writer.Align();

                    //writer.Write(0);

                    metaAsset = ms.ToArray();
                }
            return(new AssetsReplacerFromMemory(0, pathId, 0x96, 0xFFFF, metaAsset));
        }
Ejemplo n.º 2
0
        private static AssetsReplacer CreatePrefabAsset(long rootId)
        {
            //the 2017 cldb doesn't have prefab in it so
            //we're on our own with binary writer again

            MemoryStream     ms     = new MemoryStream();
            AssetsFileWriter writer = new AssetsFileWriter(ms);

            writer.bigEndian = false;
            writer.Write((uint)1);

            writer.Write(0);
            writer.Write((long)0);

            writer.Write(0);
            writer.Write(0);

            writer.Write(0);
            writer.Write((long)0);

            writer.Write(0);
            writer.Write(rootId);

            writer.Write((byte)0);
            writer.Align();

            return(new AssetsReplacerFromMemory(0, 1, 0x3e9, 0xffff, ms.ToArray()));
        }
Ejemplo n.º 3
0
 public ulong Write(ulong absFilePos, AssetsFileWriter writer, uint format)
 {
     writer.Write(len);
     for (int i = 0; i < len; i++)
     {
         writer.Write(items[i].fileID);
         writer.Write(items[i].pathID);
     }
     return(writer.Position);
 }
 public void Write(AssetsFileWriter writer)
 {
     writer.WriteNullTerminated(signature);
     writer.Write(fileVersion);
     writer.WriteNullTerminated(minPlayerVersion);
     writer.WriteNullTerminated(fileEngineVersion);
     writer.Write(totalFileSize);
     writer.Write(compressedSize);
     writer.Write(decompressedSize);
     writer.Write(flags);
 }
 public bool Write(AssetsFileWriter writer, ulong curFilePos /*, AssetsFileVerifyLogger errorLogger = NULL*/)
 {
     writer.Position = curFilePos;
     writer.WriteNullTerminated(signature);
     writer.Write(fileVersion);
     writer.WriteNullTerminated(minPlayerVersion);
     writer.WriteNullTerminated(fileEngineVersion);
     writer.Write(totalFileSize);
     writer.Write(compressedSize);
     writer.Write(decompressedSize);
     writer.Write(flags);
     return(true);
 }
Ejemplo n.º 6
0
        private static AssetsReplacer CreateSceneMetadataMonoBehaviour(long goPid, long id, string sceneName, List <long> usedIds)
        {
            byte[] data;
            using (MemoryStream ms = new MemoryStream())
                using (AssetsFileWriter w = new AssetsFileWriter(ms))
                {
                    w.bigEndian = false;
                    w.Write(0);
                    w.Write(goPid);
                    w.Write(1);
                    w.Write(2);
                    w.Write((long)11500000);
                    w.WriteCountStringInt32("");
                    w.Align();

                    w.WriteCountStringInt32(sceneName);
                    w.Align();
                    w.Write(usedIds.Count);
                    foreach (long usedId in usedIds)
                    {
                        w.Write(usedId);
                    }
                    w.Align();
                    w.Write(hkweVersion);
                    data = ms.ToArray();
                }
            return(new AssetsReplacerFromMemory(0, (ulong)id, 0x72, 0x0001, data));
        }
Ejemplo n.º 7
0
        }//Minimum AssetsFile format : 6

        public ulong Write(ulong absFilePos, AssetsFileWriter writer, uint version)
        {
            writer.WriteNullTerminated(unityVersion);
            writer.Write(this.version);
            writer.Write(hasTypeTree);
            writer.Write(fieldCount);
            for (int i = 0; i < fieldCount; i++)
            {
                pTypes_Unity5[i].Write(hasTypeTree, writer.Position, writer, version);
            }
            if (version < 0x0E)
            {
                writer.WriteUInt24(dwUnknown);
            }
            return(writer.Position);
        }
Ejemplo n.º 8
0
        private static byte[] FixTexture2DFast(AssetsFileInstance inst, AssetFileInfoEx inf)
        {
            AssetsFileReader r = inst.file.reader;

            r.Position  = inf.absoluteFilePos;
            r.Position += (ulong)r.ReadInt32() + 4;
            r.Align();
            r.Position += 0x48;
            r.Position += (ulong)r.ReadInt32() + 4;
            r.Align();
            r.Position += 0x8;
            ulong  filePathPos        = r.Position;
            int    assetLengthMinusFP = (int)(filePathPos - inf.absoluteFilePos);
            string filePath           = r.ReadCountStringInt32();
            string directory          = Path.GetDirectoryName(inst.path);
            string fixedPath          = Path.Combine(directory, filePath);

            byte[] newData = new byte[assetLengthMinusFP + 4 + fixedPath.Length];
            r.Position = inf.absoluteFilePos;
            //imo easier to write it with binary writer than manually copy the bytes
            using (MemoryStream ms = new MemoryStream())
                using (AssetsFileWriter w = new AssetsFileWriter(ms))
                {
                    w.bigEndian = false;
                    w.Write(r.ReadBytes(assetLengthMinusFP));
                    w.WriteCountStringInt32(fixedPath);
                    var ret = ms.ToArray();
                    if (ret == null)
                    {
                        return(null);
                    }
                    return(ret);
                }
        }
Ejemplo n.º 9
0
 //AssetsBundleFile
 public static void Write(this AssetsBundleFile file, AssetsFileWriter writer, byte[] assetsFileBinary /*AssetsFile assetsFile, AssetsReplacer[] replacers*/)
 {
     file.bundleHeader6.Write(writer, 0);
     file.bundleInf6.Write(writer, writer.Position);
     writer.Write(assetsFileBinary);
     //assetsFile.Write(writer, writer.Position, replacers, 0);
 }
 public void Write(AssetsFileWriter writer)
 {
     writer.Write(str.stringTableOffset);
     if (!fromStringTable)
     {
         writer.WriteCountString(str.@string);
     }
 }
Ejemplo n.º 11
0
        private static byte[] AddMetadataMonobehaviour(byte[] data, long behaviourId)
        {
            //it seems unity is so broken that after something other than
            //gameobjects are added to the asset list, you can't add any
            //monobehaviour components to gameobjects after it or it crashes
            //anyway, since I'm stuck on this one and I can't really push
            //to the beginning of the list, I'll just put the info onto
            //the first gameobject in the scene

            using (MemoryStream fms = new MemoryStream(data))
                using (AssetsFileReader fr = new AssetsFileReader(fms))
                {
                    fr.bigEndian = false;
                    int componentSize      = fr.ReadInt32();
                    List <AssetPPtr> pptrs = new List <AssetPPtr>();
                    for (int i = 0; i < componentSize; i++)
                    {
                        int  fileId = fr.ReadInt32();
                        long pathId = fr.ReadInt64();

                        //this gets rid of assets that have no reference
                        if (!(fileId == 0 && pathId == 0))
                        {
                            pptrs.Add(new AssetPPtr((uint)fileId, (ulong)pathId));
                        }
                    }
                    //add reference to Metadata mb
                    pptrs.Add(new AssetPPtr(0, (ulong)behaviourId));

                    int assetLengthMinusCP = (int)(data.Length - 4 - (componentSize * 12));

                    using (MemoryStream ms = new MemoryStream())
                        using (AssetsFileWriter w = new AssetsFileWriter(ms))
                        {
                            w.bigEndian = false;
                            w.Write(pptrs.Count);
                            foreach (AssetPPtr pptr in pptrs)
                            {
                                w.Write(pptr.fileID);
                                w.Write(pptr.pathID);
                            }
                            w.Write(fr.ReadBytes(assetLengthMinusCP));
                            return(ms.ToArray());
                        }
                }
        }
Ejemplo n.º 12
0
        //this one has to work differently since we already modified the value field
        //so we save it to a stream and read from it manually so it works faster
        //note it may be better to loop through all objects but this would be slower
        //in the future, all components should be added so we won't need this
        private static byte[] FixGameObjectFast(AssetsFileInstance inst, AssetFileInfoEx inf, AssetTypeValueField field, ulong editDifferPid)
        {
            //dump current data to ms
            using (MemoryStream fms = new MemoryStream())
                using (AssetsFileWriter fw = new AssetsFileWriter(fms))
                {
                    fw.bigEndian = false;
                    field.Write(fw);
                    fms.Position = 0;

                    AssetsFileReader r = new AssetsFileReader(fms);
                    r.bigEndian = false;
                    int componentSize      = r.ReadInt32();
                    List <AssetPPtr> pptrs = new List <AssetPPtr>();
                    for (int i = 0; i < componentSize; i++)
                    {
                        int  fileId = r.ReadInt32();
                        long pathId = r.ReadInt64();

                        //this gets rid of assets that have no reference
                        if (!(fileId == 0 && pathId == 0))
                        {
                            pptrs.Add(new AssetPPtr((uint)fileId, (ulong)pathId));
                        }
                    }
                    //add reference to EditDiffer mb
                    pptrs.Add(new AssetPPtr(0, editDifferPid));

                    int assetLengthMinusCP = (int)(inf.curFileSize - 4 - (componentSize * 12));

                    using (MemoryStream ms = new MemoryStream())
                        using (AssetsFileWriter w = new AssetsFileWriter(ms))
                        {
                            w.bigEndian = false;
                            w.Write(pptrs.Count);
                            foreach (AssetPPtr pptr in pptrs)
                            {
                                w.Write(pptr.fileID);
                                w.Write(pptr.pathID);
                            }
                            w.Write(r.ReadBytes(assetLengthMinusCP));
                            return(ms.ToArray());
                        }
                }
        }
Ejemplo n.º 13
0
 public ulong Write(AssetsFileWriter writer, ulong filePos)
 {
     writer.Write(str.stringTableOffset);
     if (!fromStringTable)
     {
         writer.WriteCountString(str.@string);
     }
     return(writer.Position);
 }
Ejemplo n.º 14
0
 public ulong Write(ulong curFilePos, AssetsFileWriter writer)
 {
     writer.Write(version);
     writer.Write(depth);
     writer.Write(isArray);
     writer.Write(typeStringOffset);
     writer.Write(nameStringOffset);
     writer.Write(size);
     writer.Write(index);
     writer.Write(flags);
     return(writer.Position);
 }
Ejemplo n.º 15
0
        public static byte[] CreateBlankAssets(string engineVersion, List <Type_0D> types)
        {
            using (MemoryStream ms = new MemoryStream())
                using (AssetsFileWriter writer = new AssetsFileWriter(ms))
                {
                    AssetsFileHeader header = new AssetsFileHeader()
                    {
                        metadataSize   = 0,
                        fileSize       = 0x1000,
                        format         = 0x11,
                        offs_firstFile = 0x1000,
                        endianness     = 0,
                        unknown        = new byte[] { 0, 0, 0 }
                    };
                    TypeTree typeTree = new TypeTree()
                    {
                        unityVersion  = engineVersion,
                        version       = 0x5,
                        hasTypeTree   = true,
                        fieldCount    = (uint)types.Count(),
                        pTypes_Unity5 = types.ToArray()
                    };


                    header.Write(writer.Position, writer);
                    writer.bigEndian = false;
                    typeTree.Write(writer.Position, writer, 0x11);
                    writer.Write((uint)0);
                    writer.Align();
                    //preload table and dependencies
                    writer.Write((uint)0);
                    writer.Write((uint)0);

                    //due to a write bug in at.net we have to pad to 0x1000
                    while (ms.Position < 0x1000)
                    {
                        writer.Write((byte)0);
                    }

                    return(ms.ToArray());
                }
        }
Ejemplo n.º 16
0
 //Write doesn't compress
 public void Write(AssetsFileWriter writer)
 {
     writer.Write(checksumHigh);
     writer.Write(checksumLow);
     writer.Write(blockCount);
     for (int i = 0; i < blockCount; i++)
     {
         writer.Write(blockInf[i].decompressedSize);
         writer.Write(blockInf[i].compressedSize);
         writer.Write(blockInf[i].flags);
     }
     writer.Write(directoryCount);
     for (int i = 0; i < directoryCount; i++)
     {
         writer.Write(dirInf[i].offset);
         writer.Write(dirInf[i].decompressedSize);
         writer.Write(dirInf[i].flags);
         writer.WriteNullTerminated(dirInf[i].name);
     }
 }
Ejemplo n.º 17
0
        public void Write(AssetsFileWriter writer)
        {
            writer.bigEndian = false;

            writer.Write(Encoding.ASCII.GetBytes(magic));

            writer.Write(includesCldb);

            writer.WriteCountStringInt16(modName);
            writer.WriteCountStringInt16(modCreators);
            writer.WriteCountStringInt16(modDescription);

            if (includesCldb)
            {
                addedTypes.Write(writer);
                writer.Position = addedTypes.header.stringTablePos + addedTypes.header.stringTableLen;
            }

            writer.Write(affectedFiles.Count);
            for (int i = 0; i < affectedFiles.Count; i++)
            {
                InstallerPackageAssetsDesc desc = affectedFiles[i];
                writer.Write(desc.isBundle);
                writer.WriteCountStringInt16(desc.path);

                writer.Write(desc.replacers.Count);
                for (int j = 0; j < desc.replacers.Count; j++)
                {
                    object repObj = desc.replacers[j];
                    if (repObj is AssetsReplacer repAsset)
                    {
                        repAsset.WriteReplacer(writer);
                    }
                    else if (repObj is BundleReplacer repBundle)
                    {
                        repBundle.WriteReplacer(writer);
                    }
                }
            }
        }
Ejemplo n.º 18
0
 //Write doesn't compress
 public bool Write(AssetsFileWriter writer, ulong curFilePos /*, AssetsFileVerifyLogger errorLogger = NULL*/)
 {
     writer.Position = curFilePos;
     writer.Write(checksumHigh);
     writer.Write(checksumLow);
     writer.Write(blockCount);
     for (int i = 0; i < blockCount; i++)
     {
         writer.Write(blockInf[i].decompressedSize);
         writer.Write(blockInf[i].compressedSize);
         writer.Write(blockInf[i].flags);
     }
     writer.Write(directoryCount);
     for (int i = 0; i < directoryCount; i++)
     {
         writer.Write(dirInf[i].offset);
         writer.Write(dirInf[i].decompressedSize);
         writer.Write(dirInf[i].flags);
         writer.WriteNullTerminated(dirInf[i].name);
     }
     return(true);
 }
Ejemplo n.º 19
0
        /////////////////////////////////////////////////////////
        // nope nothing to see here
        /////////////////////////////////////////////////////////

        private static AssetsReplacer CreateEditDifferMonoBehaviour(long goPid, AssetID origGoPptr, long id, Random rand)
        {
            byte[] data;
            using (MemoryStream ms = new MemoryStream())
                using (AssetsFileWriter w = new AssetsFileWriter(ms))
                {
                    w.bigEndian = false;
                    w.Write(0);
                    w.Write(goPid);
                    w.Write(1);
                    w.Write(1);
                    w.Write((long)11500000);
                    w.WriteCountStringInt32("");
                    w.Align();

                    w.Write(0);
                    w.Write(origGoPptr.pathId);
                    w.Write(origGoPptr.pathId);
                    w.Write(0);
                    w.Write(rand.Next());
                    data = ms.ToArray();
                }
            return(new AssetsReplacerFromMemory(0, (ulong)id, 0x72, 0x0000, data));
        }
Ejemplo n.º 20
0
 private static AssetsReplacer CreateSceneMetadataGameObject(long tfPid, long mbPid, long id)
 {
     byte[] data;
     using (MemoryStream ms = new MemoryStream())
         using (AssetsFileWriter w = new AssetsFileWriter(ms))
         {
             w.bigEndian = false;
             w.Write(2);
             w.Write(0);
             w.Write(tfPid);
             w.Write(0);
             w.Write(mbPid);
             w.Write(0);
             w.Align();
             w.WriteCountStringInt32("<//Hkwe Scene Metadata//>");
             w.Align();
             w.Write((ushort)0);
             w.Write((byte)1);
             data = ms.ToArray();
         }
     return(new AssetsReplacerFromMemory(0, (ulong)id, 0x01, 0xFFFF, data));
 }
        public void Write(AssetsFileWriter writer, int version)
        {
            typeName.Write(writer);
            fieldName.Write(writer);
            writer.Write(depth);
            writer.Write(isArray);
            writer.Write(size);
            switch (version)
            {
            case 1:
                writer.Write(flags2);
                break;

            case 3:
            case 4:
                writer.Write(this.version);
                writer.Write(flags2);
                break;
            }
        }
        public ulong Write(AssetsFileWriter writer, ulong filePos, int version)
        {
            typeName.Write(writer, filePos);
            fieldName.Write(writer, filePos);
            writer.Write(depth);
            writer.Write(isArray);
            writer.Write(size);
            switch (version)
            {
            case 1:
                writer.Write(flags2);
                break;

            case 3:
                writer.Write(this.version);
                writer.Write(flags2);
                break;
            }
            return(writer.Position);
        }
Ejemplo n.º 23
0
        //AssetTypeValueField
        public static void Write(this AssetTypeValueField valueField, AssetsFileWriter writer, int depth = 0)
        {
            if (valueField.templateField.isArray)
            {
                if (valueField.templateField.valueType == EnumValueTypes.ValueType_ByteArray)
                {
                    AssetTypeByteArray byteArray = valueField.value.value.asByteArray;

                    writer.Write(byteArray.size);
                    writer.Write(byteArray.data);
                    if (valueField.templateField.align)
                    {
                        writer.Align();
                    }
                }
                else
                {
                    int size = valueField.value.value.asArray.size;

                    writer.Write(size);
                    for (int i = 0; i < size; i++)
                    {
                        valueField[i].Write(writer, depth + 1);
                    }
                    if (valueField.templateField.align)
                    {
                        writer.Align();
                    }
                }
            }
            else
            {
                if (valueField.childrenCount == 0)
                {
                    switch (valueField.templateField.valueType)
                    {
                    case EnumValueTypes.ValueType_Int8:
                        writer.Write(valueField.value.value.asInt8);
                        if (valueField.templateField.align)
                        {
                            writer.Align();
                        }
                        break;

                    case EnumValueTypes.ValueType_UInt8:
                        writer.Write(valueField.value.value.asUInt8);
                        if (valueField.templateField.align)
                        {
                            writer.Align();
                        }
                        break;

                    case EnumValueTypes.ValueType_Bool:
                        writer.Write(valueField.value.value.asBool);
                        if (valueField.templateField.align)
                        {
                            writer.Align();
                        }
                        break;

                    case EnumValueTypes.ValueType_Int16:
                        writer.Write(valueField.value.value.asInt16);
                        if (valueField.templateField.align)
                        {
                            writer.Align();
                        }
                        break;

                    case EnumValueTypes.ValueType_UInt16:
                        writer.Write(valueField.value.value.asUInt16);
                        if (valueField.templateField.align)
                        {
                            writer.Align();
                        }
                        break;

                    case EnumValueTypes.ValueType_Int32:
                        writer.Write(valueField.value.value.asInt32);
                        break;

                    case EnumValueTypes.ValueType_UInt32:
                        writer.Write(valueField.value.value.asUInt32);
                        break;

                    case EnumValueTypes.ValueType_Int64:
                        writer.Write(valueField.value.value.asInt64);
                        break;

                    case EnumValueTypes.ValueType_UInt64:
                        writer.Write(valueField.value.value.asUInt64);
                        break;

                    case EnumValueTypes.ValueType_Float:
                        writer.Write(valueField.value.value.asFloat);
                        break;

                    case EnumValueTypes.ValueType_Double:
                        writer.Write(valueField.value.value.asDouble);
                        break;

                    case EnumValueTypes.ValueType_String:
                        writer.WriteCountStringInt32(valueField.value.value.asString);
                        writer.Align();
                        break;
                    }
                }
                else
                {
                    for (int i = 0; i < valueField.childrenCount; i++)
                    {
                        valueField[i].Write(writer, depth + 1);
                    }
                    if (valueField.templateField.align)
                    {
                        writer.Align();
                    }
                }
            }
        }
Ejemplo n.º 24
0
        private byte[] CreateEditDifferMonoBehaviour(long goPid, AssetTypeValueField componentArray, AssetID origGoPptr)
        {
            byte[] data;
            using (MemoryStream ms = new MemoryStream())
                using (AssetsFileWriter w = new AssetsFileWriter(ms))
                {
                    w.bigEndian = false;
                    w.Write(0);
                    w.Write(goPid);
                    w.Write(1);
                    w.Write(2);
                    w.Write((long)11500000);
                    w.WriteCountStringInt32("");
                    w.Align();

                    w.Write(0);
                    w.Write(origGoPptr.pathId);
                    w.Write(origGoPptr.pathId);
                    w.Write(0);

                    int componentArrayLength = componentArray.GetValue().AsArray().size;
                    w.Write(componentArrayLength);
                    for (int i = 0; i < componentArrayLength; i++)
                    {
                        AssetTypeValueField component = componentArray[i].Get("component");
                        int  m_FileID = component.Get("m_FileID").GetValue().AsInt();
                        long m_PathID = component.Get("m_PathID").GetValue().AsInt64();
                        if (m_PathID == 0) //removed (monobehaviour)
                        {
                            w.Write((long)-1);
                        }
                        else if (m_FileID == 0) //correct file
                        {
                            w.Write(m_PathID);
                        }
                        else //another file (shouldn't happen?)
                        {
                            w.Write((long)0);
                        }
                    }

                    w.Write(0 /*rand.Next()*/);
                    data = ms.ToArray();
                }
            return(data);
        }
Ejemplo n.º 25
0
        private byte[] CreateTk2DEmulatorMonoBehaviour(long goPid, Tk2dInfo tk2dInfo)
        {
            byte[] data;
            using (MemoryStream ms = new MemoryStream())
                using (AssetsFileWriter w = new AssetsFileWriter(ms))
                {
                    w.bigEndian = false;
                    w.Write(0);
                    w.Write(goPid);
                    w.Write(1);
                    w.Write(3);
                    w.Write((long)11500000);
                    w.WriteCountStringInt32("");
                    w.Align();

                    w.Write(tk2dInfo.positions.Length);
                    for (int i = 0; i < tk2dInfo.positions.Length; i++)
                    {
                        Vector3 position = tk2dInfo.positions[i];
                        w.Write(position.x);
                        w.Write(position.y);
                        w.Write(position.z);
                    }
                    w.Align();

                    w.Write(tk2dInfo.uvs.Length);
                    for (int i = 0; i < tk2dInfo.uvs.Length; i++)
                    {
                        Vector3 uv = tk2dInfo.uvs[i];
                        w.Write(uv.x);
                        w.Write(uv.y);
                    }
                    w.Align();

                    w.Write(tk2dInfo.indices.Length);
                    for (int i = 0; i < tk2dInfo.indices.Length; i++)
                    {
                        w.Write(tk2dInfo.indices[i]);
                    }
                    w.Align();

                    data = ms.ToArray();
                }
            return(data);
        }
Ejemplo n.º 26
0
        public static AssetsReplacer CreateBundleInformation(Dictionary <AssetID, ulong> files, List <ulong> spriteIds, ulong pathId)
        {
            byte[] metaAsset = null;
            using (MemoryStream ms = new MemoryStream())
                using (AssetsFileWriter writer = new AssetsFileWriter(ms))
                {
                    writer.bigEndian = false;
                    writer.Write(0);
                    writer.Write((uint)(1 + files.Count + spriteIds.Count)); //spriteIds is risky, we don't know if all are going to be written

                    writer.Write(0);
                    writer.Write((ulong)2);
                    foreach (KeyValuePair <AssetID, ulong> file in files)
                    {
                        writer.Write(0);
                        writer.Write(file.Value);
                    }
                    writer.Align();

                    foreach (KeyValuePair <AssetID, ulong> file in files)
                    {
                        if (spriteIds.Contains(file.Value))
                        {
                            writer.Write(0);
                            writer.Write(file.Value);
                        }
                    }
                    writer.Align();

                    int index = 1;
                    writer.Write((uint)files.Count);
                    foreach (KeyValuePair <AssetID, ulong> file in files)
                    {
                        writer.WriteCountStringInt32(file.Key.fileName + "/" + file.Key.pathId + ".dat");
                        writer.Align();
                        writer.Write(index++);
                        writer.Write(1);
                        writer.Write(0);
                        writer.Write(file.Value);
                    }
                    writer.Align();

                    writer.Write(0);
                    writer.Write(1);
                    writer.Write(0);
                    writer.Write((ulong)2);

                    writer.Write((uint)1);

                    writer.Write(0);

                    writer.Write(0);

                    writer.Write((uint)0);

                    writer.Write((uint)0);

                    writer.Write(7);

                    writer.Write(0);

                    metaAsset = ms.ToArray();
                }
            return(new AssetsReplacerFromMemory(0, pathId, 0x8E, 0xFFFF, metaAsset));
        }
Ejemplo n.º 27
0
        private void ImportTextAssetLoop()
        {
            Stack <bool> alignStack = new Stack <bool>();

            while (true)
            {
                string?line = sr.ReadLine();
                if (line == null)
                {
                    return;
                }

                int thisDepth = 0;
                while (line[thisDepth] == ' ')
                {
                    thisDepth++;
                }

                if (line[thisDepth] == '[') //array index, ignore
                {
                    continue;
                }

                if (thisDepth < alignStack.Count)
                {
                    while (thisDepth < alignStack.Count)
                    {
                        if (alignStack.Pop())
                        {
                            aw.Align();
                        }
                    }
                }

                bool   align    = line.Substring(thisDepth, 1) == "1";
                int    typeName = thisDepth + 2;
                int    eqSign   = line.IndexOf('=');
                string valueStr = line.Substring(eqSign + 1).Trim();

                if (eqSign != -1)
                {
                    string check = line.Substring(typeName);
                    //this list may be incomplete
                    if (StartsWithSpace(check, "bool"))
                    {
                        aw.Write(bool.Parse(valueStr));
                    }
                    else if (StartsWithSpace(check, "UInt8"))
                    {
                        aw.Write(byte.Parse(valueStr));
                    }
                    else if (StartsWithSpace(check, "SInt8"))
                    {
                        aw.Write(sbyte.Parse(valueStr));
                    }
                    else if (StartsWithSpace(check, "UInt16"))
                    {
                        aw.Write(ushort.Parse(valueStr));
                    }
                    else if (StartsWithSpace(check, "SInt16"))
                    {
                        aw.Write(short.Parse(valueStr));
                    }
                    else if (StartsWithSpace(check, "unsigned int"))
                    {
                        aw.Write(uint.Parse(valueStr));
                    }
                    else if (StartsWithSpace(check, "int"))
                    {
                        aw.Write(int.Parse(valueStr));
                    }
                    else if (StartsWithSpace(check, "UInt64"))
                    {
                        aw.Write(ulong.Parse(valueStr));
                    }
                    else if (StartsWithSpace(check, "SInt64"))
                    {
                        aw.Write(long.Parse(valueStr));
                    }
                    else if (StartsWithSpace(check, "float"))
                    {
                        aw.Write(float.Parse(valueStr));
                    }
                    else if (StartsWithSpace(check, "double"))
                    {
                        aw.Write(double.Parse(valueStr));
                    }
                    else if (StartsWithSpace(check, "string"))
                    {
                        int    firstQuote  = valueStr.IndexOf('"');
                        int    lastQuote   = valueStr.LastIndexOf('"');
                        string valueStrFix = valueStr.Substring(firstQuote + 1, lastQuote - firstQuote - 1);
                        valueStrFix = valueStrFix
                                      .Replace("\\r", "\r")
                                      .Replace("\\n", "\n");
                        aw.WriteCountStringInt32(valueStrFix);
                    }

                    if (align)
                    {
                        aw.Align();
                    }
                }
                else
                {
                    alignStack.Push(align);
                }
            }
        }
Ejemplo n.º 28
0
        public static void CreateBlankAssets(MemoryStream ms, string engineVersion, uint formatVersion, uint typeTreeVersion, bool hasTypeTree = false)
        {
            AssetsFileWriter writer = new AssetsFileWriter(ms);

            AssetsFileHeader header = new AssetsFileHeader()
            {
                metadataSize    = 0,
                fileSize        = -1,
                format          = formatVersion,
                firstFileOffset = -1,
                endianness      = 0,
                unknown         = new byte[] { 0, 0, 0 }
            };

            TypeTree typeTree = new TypeTree()
            {
                unityVersion = engineVersion,
                version      = typeTreeVersion,
                hasTypeTree  = hasTypeTree,
                fieldCount   = 0,
                unity5Types  = new List <Type_0D>()
            };

            header.Write(writer);
            typeTree.Write(writer, formatVersion);

            writer.Write((uint)0); //AssetCount
            writer.Align();

            //preload table and dependencies
            writer.Write((uint)0);
            writer.Write((uint)0);

            //secondaryTypeCount
            if (header.format >= 0x14)
            {
                writer.Write(0);
            }

            uint metadataSize = (uint)(writer.Position - 0x13);

            if (header.format >= 0x16)
            {
                metadataSize -= 0x1c;
            }

            if (writer.Position < 0x1000)
            {
                while (writer.Position < 0x1000)
                {
                    writer.Write((byte)0x00);
                }
            }
            else
            {
                if (writer.Position % 16 == 0)
                {
                    writer.Position += 16;
                }
                else
                {
                    writer.Align16();
                }
            }

            long endPosition = writer.Position;

            header.fileSize        = endPosition;
            header.firstFileOffset = endPosition;
            header.metadataSize    = metadataSize;

            writer.Position = 0;
            header.Write(writer);

            writer.Position = endPosition;
        }
Ejemplo n.º 29
0
        public static byte[] CreateBundleFromLevel(AssetsManager am, /*byte[] data,*/ AssetsFileInstance inst, string sceneName, DiffFile diffFile, string bunPath)
        {
            AssetsFile      file  = inst.file;
            AssetsFileTable table = inst.table;

            string folderName = Path.GetDirectoryName(inst.path);
            //string sceneName = Path.GetFileNameWithoutExtension(inst.path) + "_mod";

            List <AssetsReplacer> assetsSA = new List <AssetsReplacer>();

            List <AssetFileInfoEx> infos = table.pAssetFileInfo.ToList();

            //List<int> typeIds = new List<int>();
            //foreach (AssetFileInfoEx info in infos)
            //{
            //    int typeId = (int)info.curFileType;
            //    if (!typeIds.Contains(typeId) && typeId != 0x72)
            //        typeIds.Add(typeId);
            //}

            assetsSA.Add(PreloadData.CreatePreloadData(1));
            assetsSA.Add(BundleMeta.CreateBundleInformation(sceneName, 2));

            //todo: pull from original assets file, cldb is not always update to date
            List <Type_0D> types = new List <Type_0D>();
            //foreach (int typeId in typeIds)
            //{
            //    types.Add(C2T5.Cldb2TypeTree(am.classFile, typeId));
            //}

            List <Type_0D> typesSA = new List <Type_0D>
            {
                C2T5.Cldb2TypeTree(am.classFile, 0x96), //PreloadData
                C2T5.Cldb2TypeTree(am.classFile, 0x8E)  //AssetBundle
            };

            const string ver = "2017.4.10f1";

            List <AssetsReplacer> replacers = new List <AssetsReplacer>();

            //UnityEngine.Debug.Log("HKWE DM " + diffFile.magic);
            //UnityEngine.Debug.Log("HKWE GC " + diffFile.changes.Count + diffFile.adds.Count + diffFile.removes.Count);
            //AssetsReplacerFromMemory mem = MoveTest.RunMoveTest(table.getAssetInfo(2642), am.GetATI(file, table.getAssetInfo(2642)).GetBaseField(), 2642) as AssetsReplacerFromMemory;
            foreach (GameObjectChange goChange in diffFile.changes)
            {
                //UnityEngine.Debug.Log("HKWE GO " + goChange.pathId);
                foreach (ComponentChangeOrAdd compChange in goChange.changes)
                {
                    AssetFileInfoEx     goInfo      = table.getAssetInfo((ulong)goChange.pathId);
                    AssetTypeValueField goBaseField = am.GetATI(file, goInfo).GetBaseField();

                    AssetTypeValueField         compPptr = goBaseField.Get("m_Component").Get("Array")[(uint)compChange.componentIndex].Get("component");
                    AssetsManager.AssetExternal compExt  = am.GetExtAsset(inst, compPptr);

                    AssetFileInfoEx     compInfo      = compExt.info;
                    AssetTypeValueField compBaseField = compExt.instance.GetBaseField();

                    //UnityEngine.Debug.Log("HKWE LR " + compInfo.index);
                    AssetsReplacer imAlreadyReplacer = ComponentDiffReplacer.DiffComponent(compInfo, compBaseField, am.classFile, compChange, compInfo.index);
                    replacers.Add(imAlreadyReplacer);
                }
            }
            AssetsManager amBun = new AssetsManager();                                                                          //we create a new manager because the two filenames will probably conflict

            amBun.classFile = am.classFile;                                                                                     //we can just reuse the classfile which is kinda hacky
            AssetsFileInstance bunInst = amBun.LoadAssetsFile(new MemoryStream(GetBundleData(bunPath, 0)), "HKWEDiffs", false); //placeholder path since we have no deps

            //rearrange the pathids immediately after the
            //last one from the level to keep unity happy
            ulong levelLargestPathID = 0;

            foreach (AssetFileInfoEx inf in table.pAssetFileInfo)
            {
                if (inf.index > levelLargestPathID)
                {
                    levelLargestPathID = inf.index;
                }
            }
            ReferenceCrawler.ReorderIds(amBun, bunInst, levelLargestPathID + 1);

            byte[] bunSAInst = GetBundleData(bunPath, 1);
            //HashSet<ulong> addedDeps = new HashSet<ulong>();
            foreach (AssetFileInfoEx inf in bunInst.table.pAssetFileInfo)
            {
                replacers.Add(MakeReplacer(inf.index, am, bunInst, inst, inf, bunSAInst, types));
            }
            //foreach (GameObjectInfo inf in diffFile.infos)
            //{
            //    Debug.Log("7");
            //    ulong bunPathId = GetBundlePathId(amBun, bunInst, inf);
            //
            //    AssetFileInfoEx objInf = bunInst.table.getAssetInfo(bunPathId);
            //    replacers.Add(MakeReplacer(bunPathId, am, bunInst, inst, objInf, bunSAInst, types));
            //
            //    List<ulong> deps = ReferenceCrawler.CrawlPPtrs(amBun, bunInst, bunPathId);
            //    foreach (ulong dep in deps)
            //    {
            //        if (!addedDeps.Contains(dep))
            //        {
            //            addedDeps.Add(dep);
            //            AssetFileInfoEx depInf = bunInst.table.getAssetInfo(dep);
            //            //if (depInf.curFileType == 0x01 || depInf.curFileType == 0x04 || depInf.curFileType == 0xD4 || depInf.curFileType == 0x15 || depInf.curFileType == 0xD5)
            //            //{
            //            //    continue;
            //            //}
            //            replacers.Add(MakeReplacer(dep, am, bunInst, inst, depInf, bunSAInst, types));
            //        }
            //    }
            //    ////its possible to get a collision but very unlikely since unity already randomizes ids which are 8 bytes long
            //    ////there's nothing here to test if a collision would be created so just hope that you don't win the lottery
            //    //ulong bunPathId = GetBundlePathId(amBun, bunInst, inf);
            //    ////AssetFileInfoEx afInf = bunInst.table.getAssetInfo(bunPathId);
            //    ////replacers.Add(MakeReplacer(bunPathId, afInf, bunInst.stream));
            //    //List<ulong> deps = ReferenceCrawler.CrawlPPtrs(am, bunInst, bunPathId);
            //    ////if (info.curFileType == 0x01 || info.curFileType == 0x04 || info.curFileType == 0xD4)
            //    ////{
            //    ////    continue;
            //    ////}
            //    //foreach (ulong dep in deps)
            //    //{
            //    //    AssetFileInfoEx depInf = bunInst.table.getAssetInfo(dep);
            //    //    //MakeReplacer(dep, am, bunInst, inst, depInf, bunSAInst, types);
            //    //    AssetsReplacerFromMemory ar = MakeReplacer(dep, am, bunInst, inst, depInf, bunSAInst, types);
            //    //    //todo- I guess this was just for testing purposes to block out everything, remove this at some point
            //    //    if (depInf.curFileType == 0x01 || depInf.curFileType == 0x04 || depInf.curFileType == 0xD4 || depInf.curFileType == 0x15 || depInf.curFileType == 0xD5) //depInf.curFileType == 0x1C
            //    //    {
            //    //        continue;
            //    //    }
            //    //    replacers.Add(ar);
            //    //}
            //}

            byte[] data = null;
            using (MemoryStream ms = new MemoryStream())
                using (AssetsFileWriter writer = new AssetsFileWriter(ms))
                {
                    //file.typeTree.hasTypeTree = true; //so we don't have to calculate hashes
                    //foreach (Type_0D type in file.typeTree.pTypes_Unity5)
                    //{
                    //    if (!types.Any(t => t.classId == type.classId))
                    //    {
                    //        types.Insert(0, C2T5.Cldb2TypeTree(am.classFile, type.classId));
                    //    }
                    //}
                    file.typeTree.pTypes_Unity5 = file.typeTree.pTypes_Unity5.Concat(types.ToArray()).ToArray();
                    //file.typeTree.pTypes_Unity5 = types.ToArray();
                    file.typeTree.fieldCount = (uint)file.typeTree.pTypes_Unity5.Length;
                    //file.typeTree.fieldCount = (uint)types.Count;
                    file.Write(writer, 0, replacers.ToArray(), 0);
                    data = ms.ToArray();
                }
            //File.WriteAllBytes("_bundlefinal1.unity3d", data);

            byte[]     blankDataSA = BundleCreator.CreateBlankAssets(ver, typesSA);
            AssetsFile blankFileSA = new AssetsFile(new AssetsFileReader(new MemoryStream(blankDataSA)));

            byte[] dataSA = null;
            using (MemoryStream ms = new MemoryStream())
                using (AssetsFileWriter writer = new AssetsFileWriter(ms))
                {
                    blankFileSA.Write(writer, 0, assetsSA.ToArray(), 0);
                    dataSA = ms.ToArray();
                }

            using (MemoryStream ms = new MemoryStream())
                using (AssetsFileWriter writer = new AssetsFileWriter(ms))
                {
                    AssetsBundleFile bundle = BundleCreator.CreateBlankBundle(ver, data.Length, dataSA.Length, sceneName);
                    bundle.Write(writer);
                    writer.Write(dataSA);
                    writer.Write(data);
                    return(ms.ToArray());
                }
        }
Ejemplo n.º 30
0
        //AssetsFile
        public static ulong WriteFix(this AssetsFile file, AssetsFileWriter writer, ulong filePos, AssetsReplacer[] pReplacers, uint fileID, ClassDatabaseFile typeMeta = null)
        {
            file.header.Write(writer.Position, writer);

            for (int i = 0; i < pReplacers.Length; i++)
            {
                AssetsReplacer replacer = pReplacers[i];
                if (!file.typeTree.pTypes_Unity5.Any(t => t.classId == replacer.GetClassID()))
                {
                    Type_0D type = new Type_0D()
                    {
                        classId           = replacer.GetClassID(),
                        unknown16_1       = 0,
                        scriptIndex       = 0xFFFF,
                        unknown5          = 0,
                        unknown6          = 0,
                        unknown7          = 0,
                        unknown8          = 0,
                        typeFieldsExCount = 0,
                        stringTableLen    = 0,
                        pStringTable      = ""
                    };
                    file.typeTree.pTypes_Unity5.Concat(new Type_0D[] { type });
                }
            }
            file.typeTree.Write(writer.Position, writer, file.header.format);

            int initialSize  = (int)(AssetFileInfo.GetSize(file.header.format) * file.AssetCount);
            int newSize      = (int)(AssetFileInfo.GetSize(file.header.format) * (file.AssetCount + pReplacers.Length));
            int appendedSize = newSize - initialSize;

            file.reader.Position = file.AssetTablePos;

            List <AssetFileInfo>  originalAssetInfos = new List <AssetFileInfo>();
            List <AssetFileInfo>  assetInfos         = new List <AssetFileInfo>();
            List <AssetsReplacer> currentReplacers   = pReplacers.ToList();
            uint currentOffset = 0;

            //-write all original assets, modify sizes if needed and skip those to be removed
            for (int i = 0; i < file.AssetCount; i++)
            {
                AssetFileInfo info = new AssetFileInfo();
                info.Read(file.header.format, file.reader.Position, file.reader, file.reader.bigEndian);
                originalAssetInfos.Add(info);
                AssetsReplacer replacer = currentReplacers.FirstOrDefault(n => n.GetPathID() == info.index);
                if (replacer != null)
                {
                    currentReplacers.Remove(replacer);
                    if (replacer.GetReplacementType() == AssetsReplacementType.AssetsReplacement_AddOrModify)
                    {
                        int classIndex = Array.FindIndex(file.typeTree.pTypes_Unity5, t => t.classId == replacer.GetClassID());
                        info = new AssetFileInfo()
                        {
                            index               = replacer.GetPathID(),
                            offs_curFile        = currentOffset,
                            curFileSize         = (uint)replacer.GetSize(),
                            curFileTypeOrIndex  = (uint)classIndex,
                            inheritedUnityClass = (ushort)replacer.GetClassID(), //-what is this
                            scriptIndex         = replacer.GetMonoScriptID(),
                            unknown1            = 0
                        };
                    }
                    else if (replacer.GetReplacementType() == AssetsReplacementType.AssetsReplacement_Remove)
                    {
                        continue;
                    }
                }
                currentOffset += info.curFileSize;
                uint pad = 8 - (currentOffset % 8);
                if (pad != 8)
                {
                    currentOffset += pad;
                }

                assetInfos.Add(info);
            }

            //-write new assets
            while (currentReplacers.Count > 0)
            {
                AssetsReplacer replacer = currentReplacers.First();
                if (replacer.GetReplacementType() == AssetsReplacementType.AssetsReplacement_AddOrModify)
                {
                    int           classIndex = Array.FindIndex(file.typeTree.pTypes_Unity5, t => t.classId == replacer.GetClassID());
                    AssetFileInfo info       = new AssetFileInfo()
                    {
                        index               = replacer.GetPathID(),
                        offs_curFile        = currentOffset,
                        curFileSize         = (uint)replacer.GetSize(),
                        curFileTypeOrIndex  = (uint)classIndex,
                        inheritedUnityClass = (ushort)replacer.GetClassID(),
                        scriptIndex         = replacer.GetMonoScriptID(),
                        unknown1            = 0
                    };
                    currentOffset += info.curFileSize;
                    uint pad = 8 - (currentOffset % 8);
                    if (pad != 8)
                    {
                        currentOffset += pad;
                    }

                    assetInfos.Add(info);
                }
                currentReplacers.Remove(replacer);
            }

            writer.Write(assetInfos.Count);
            writer.Align();
            for (int i = 0; i < assetInfos.Count; i++)
            {
                assetInfos[i].Write(file.header.format, writer.Position, writer);
            }

            file.preloadTable.Write(writer.Position, writer, file.header.format);

            file.dependencies.Write(writer.Position, writer, file.header.format);

            uint metadataSize = (uint)writer.Position - 0x13;

            //-for padding only. if all initial data before assetData is more than 0x1000, this is skipped
            while (writer.Position < 0x1000 /*header.offs_firstFile*/)
            {
                writer.Write((byte)0x00);
            }

            writer.Align16();

            uint offs_firstFile = (uint)writer.Position;

            for (int i = 0; i < assetInfos.Count; i++)
            {
                AssetFileInfo  info     = assetInfos[i];
                AssetsReplacer replacer = pReplacers.FirstOrDefault(n => n.GetPathID() == info.index);
                if (replacer != null)
                {
                    if (replacer.GetReplacementType() == AssetsReplacementType.AssetsReplacement_AddOrModify)
                    {
                        replacer.Write(writer.Position, writer);
                        writer.Align8();
                    }
                    else if (replacer.GetReplacementType() == AssetsReplacementType.AssetsReplacement_Remove)
                    {
                        continue;
                    }
                }
                else
                {
                    AssetFileInfo originalInfo = originalAssetInfos.FirstOrDefault(n => n.index == info.index);
                    if (originalInfo != null)
                    {
                        file.reader.Position = file.header.offs_firstFile + originalInfo.offs_curFile;
                        byte[] assetData = file.reader.ReadBytes((int)originalInfo.curFileSize);
                        writer.Write(assetData);
                        writer.Align8();
                    }
                }
            }

            file.header.offs_firstFile = offs_firstFile;

            ulong fileSizeMarker = writer.Position;

            file.reader.Position = file.header.offs_firstFile;

            writer.Position          = 0;
            file.header.metadataSize = metadataSize;
            file.header.fileSize     = (uint)fileSizeMarker;
            file.header.Write(writer.Position, writer);
            return(writer.Position);
        }