Example #1
0
 //if component doesn't know its father
 public GameObjectViewer(AssetsManager helper, AssetsFileInstance inst, AssetTypeValueField baseField, AssetFileInfoEx componentInfo)
 {
     InitializeComponent();
     this.helper        = helper;
     this.inst          = inst;
     this.baseField     = baseField;
     this.componentInfo = componentInfo;
 }
Example #2
0
    private static void FindNestedPointers(AssetsFileInstance file, AssetTypeValueField field, AssetFileInfoEx info, bool replace)
    {
        foreach (var child in field.pChildren)
        {
            if (child == null)
            {
                Debug.LogError("Found null child in under a " + field.GetFieldType() + " named " + field.GetName());
                return;
            }

            if (!child.templateField.hasValue)
            {
                //not array of values either
                if (child.templateField.isArray && child.templateField.children[1].valueType != EnumValueTypes.ValueType_None)
                {
                    return;
                }
                var type = child.templateField.type;
                if (type.StartsWith("PPtr<") && type.EndsWith(">") && child.childrenCount == 2)
                {
                    var fileId = child.Get("m_FileID").GetValue().AsInt();
                    var pathId = child.Get("m_PathID").GetValue().AsInt64();

                    if (pathId == 0)
                    {
                        //Debug.LogWarning("A " + field.GetFieldType() + " called " + field.GetName() + " has a " + type + " child with a null path: " + pathId);
                        continue;
                    }

                    var id     = AssetID.FromPPtr(file, fileId, pathId);
                    var asset  = am.GetExtAsset(file, (uint)fileId, (ulong)pathId);
                    var exists = pointers.ContainsKey(id);

                    if (replace)
                    {
                        if (exists)
                        {
                            var newId = pointers[id];

                            var isSelfAsset = IsAsset(info);
                            var isDepAsset  = newId.fileName.Equals(ASSET_LEVEL_NAME);

                            var newFileId = isDepAsset ^ isSelfAsset ? 1 : 0;

                            child.Get("m_FileID").GetValue().Set(newFileId);
                            child.Get("m_PathID").GetValue().Set(newId.pathId);
                        }
                        else
                        {
                            child.Get("m_FileID").GetValue().Set(0);
                            child.Get("m_PathID").GetValue().Set(0);
                        }
                    }
                    else
                    {
                        if (exists)
                        {
                            continue;
                        }

                        AddPointer(id, IsAsset(asset.info));
                        var baseField = asset.instance.GetBaseField();

                        if (asset.info.curFileType == 0x72)
                        {
                            var ms = baseField.Get("m_Script");
                            if (ms != null && ms.childrenCount == 2 && ms.GetFieldType().Equals("PPtr<MonoScript>"))
                            {
                                baseField = am.GetMonoBaseFieldCached(asset.file, asset.info, Path.Combine(hkDir, "Managed"));
                            }
                        }

                        FindNestedPointers(asset.file, baseField, info, false);
                    }
                }
                else
                {
                    FindNestedPointers(file, child, info, replace);
                }
            }
        }
    }
 public AssetTypeInstance GetTypeInstance(AssetsFile file, AssetFileInfoEx info, bool forceFromCldb = false)
 {
     return(new AssetTypeInstance(GetTemplateBaseField(file, info, forceFromCldb), file.reader, info.absoluteFilePos));
 }
Example #4
0
        public FsmDataInstance LoadFSM(long id)
        {
            AssetFileInfoEx     info      = curFile.table.GetAssetInfo(id);
            AssetTypeValueField baseField = am.GetMonoBaseFieldCached(curFile, info, Path.Combine(Path.GetDirectoryName(curFile.path), "Managed"));
            AssetNameResolver   namer     = new AssetNameResolver(am, curFile);

            FsmDataInstance dataInstance = new FsmDataInstance();

            AssetTypeValueField fsm               = baseField.Get("fsm");
            AssetTypeValueField states            = fsm.Get("states");
            AssetTypeValueField events            = fsm.Get("events");
            AssetTypeValueField variables         = fsm.Get("variables");
            AssetTypeValueField globalTransitions = fsm.Get("globalTransitions");
            AssetTypeValueField dataVersionField  = fsm.Get("dataVersion");

            dataInstance.fsmName = fsm.Get("name").GetValue().AsString();

            AssetTypeInstance goAti = am.GetExtAsset(curFile, baseField.Get("m_GameObject")).instance;

            if (goAti != null)
            {
                string m_Name = goAti.GetBaseField().Get("m_Name").GetValue().AsString();
                dataInstance.goName = m_Name;
            }

            if (dataVersionField.IsDummy())
            {
                dataInstance.dataVersion = fsm.Get("version").GetValue().AsInt() + 1;
            }
            else
            {
                dataInstance.dataVersion = dataVersionField.GetValue().AsInt();
            }

            dataInstance.states = new List <FsmStateData>();
            for (int i = 0; i < states.GetChildrenCount(); i++)
            {
                FsmStateData stateData = new FsmStateData();
                stateData.ActionData = new List <ActionScriptEntry>();
                stateData.state      = new FsmState(namer, states[i]);
                stateData.node       = new FsmNodeData(stateData.state);

                GetActionData(stateData.ActionData, stateData.state.actionData, dataInstance.dataVersion);

                dataInstance.states.Add(stateData);
            }

            dataInstance.events = new List <FsmEventData>();
            for (int i = 0; i < events.GetChildrenCount(); i++)
            {
                FsmEventData eventData = new FsmEventData();
                eventData.Global = events[i].Get("isGlobal").GetValue().AsBool();
                eventData.Name   = events[i].Get("name").GetValue().AsString();

                dataInstance.events.Add(eventData);
            }

            dataInstance.variables = new List <FsmVariableData>();
            GetVariableValues(dataInstance.variables, namer, variables);

            dataInstance.globalTransitions = new List <FsmNodeData>();
            for (int i = 0; i < globalTransitions.GetChildrenCount(); i++)
            {
                AssetTypeValueField globalTransitionField = globalTransitions[i];
                FsmGlobalTransition globalTransition      = new FsmGlobalTransition()
                {
                    fsmEvent       = new FsmEvent(globalTransitionField.Get("fsmEvent")),
                    toState        = globalTransitionField.Get("toState").GetValue().AsString(),
                    linkStyle      = globalTransitionField.Get("linkStyle").GetValue().AsInt(),
                    linkConstraint = globalTransitionField.Get("linkConstraint").GetValue().AsInt(),
                    colorIndex     = (byte)globalTransitionField.Get("colorIndex").GetValue().AsInt()
                };

                FsmNodeData node = new FsmNodeData(dataInstance, globalTransition);
                dataInstance.globalTransitions.Add(node);
            }

            //dataInstance.events = new List<FsmEventData>();
            //for (int i = 0; i < events.GetChildrenCount(); i++)
            //{
            //    FsmEventData eventData = new FsmEventData();
            //    AssetTypeValueField evt = events[i];
            //    eventData.Name = evt.Get("name").GetValue().AsString();
            //    eventData.Global = evt.Get("isGlobal").GetValue().AsBool();
            //}
            //
            //dataInstance.variables = new List<FsmVariableData>();
            //for (int i = 0; i < variables.GetChildrenCount(); i++)
            //{
            //    FsmVariableData variableData = new FsmVariableData();
            //    AssetTypeValueField vars = events[i];
            //}

            return(dataInstance);
        }
        public static AssetTypeValueField GetMonoBaseField(AssetsManager am, AssetsFileInstance inst, AssetFileInfoEx info, string managedPath)
        {
            AssetsFile             file      = inst.file;
            AssetTypeTemplateField baseField = new AssetTypeTemplateField();

            baseField.FromClassDatabase(am.classFile, AssetHelper.FindAssetClassByID(am.classFile, info.curFileType), 0);
            AssetTypeInstance mainAti = new AssetTypeInstance(baseField, file.reader, false, info.absoluteFilePos);

            if (file.typeTree.pTypes_Unity5[info.curFileTypeOrIndex].scriptIndex != 0xFFFF)
            {
                AssetTypeInstance scriptAti    = am.GetExtAsset(inst, mainAti.GetBaseField().Get("m_Script")).instance;
                string            scriptName   = scriptAti.GetBaseField().Get("m_Name").GetValue().AsString();
                string            assemblyName = scriptAti.GetBaseField().Get("m_AssemblyName").GetValue().AsString();
                string            assemblyPath = Path.Combine(managedPath, assemblyName);
                if (File.Exists(assemblyPath))
                {
                    MonoClass mc = new MonoClass();
                    mc.Read(scriptName, assemblyPath, inst.file.header.format);
                    AssetTypeTemplateField[] monoTemplateFields = mc.children;

                    AssetTypeTemplateField[] templateField = baseField.children.Concat(monoTemplateFields).ToArray();
                    baseField.children      = templateField;
                    baseField.childrenCount = (uint)baseField.children.Length;

                    mainAti = new AssetTypeInstance(baseField, file.reader, false, info.absoluteFilePos);
                }
            }
            return(mainAti.GetBaseField());
        }
Example #6
0
        private static void RecurseTypeReplace(AssetsManager am, AssetsFileInstance inst, AssetFileInfoEx info, AssetTypeValueField field, List <string> fileNames, Dictionary <AssetID, byte[]> ids, Dictionary <AssetID, long> aidToPid, Dictionary <long, long> gidToMid, int depth)
        {
            string p = new string(' ', depth);

            foreach (AssetTypeValueField child in field.pChildren)
            {
                //Console.WriteLine(p + child.templateField.type + " " + child.templateField.name);
                if (!child.templateField.hasValue)
                {
                    if (child == null)
                    {
                        return;
                    }
                    string typeName = child.templateField.type;
                    if (typeName.StartsWith("PPtr<") && typeName.EndsWith(">") && child.childrenCount == 2)
                    {
                        int  fileId = child.Get("m_FileID").GetValue().AsInt();
                        long pathId = child.Get("m_PathID").GetValue().AsInt64();

                        if (pathId == 0) //removed asset
                        {
                            continue;
                        }
                        if (fileId > 0)
                        {
                            throw new Exception("file id was not set correctly!");
                        }

                        fileId = -fileId;
                        string fileName = fileNames[fileId];

                        AssetID actualId = new AssetID(fileName, pathId);
                        if (!aidToPid.ContainsKey(actualId))
                        {
                            Console.WriteLine("WARNING: MISSING ID FOR " + actualId.fileName + " " + actualId.pathId + " ON " + inst.name + " " + info.index);
                            child.Get("m_PathID").GetValue().Set(0);
                        }
                        else
                        {
                            child.Get("m_PathID").GetValue().Set(aidToPid[actualId]);
                        }
                        child.Get("m_FileID").GetValue().Set(0);
                    }
                    RecurseTypeReplace(am, inst, info, child, fileNames, ids, aidToPid, gidToMid, depth + 1);
                }
            }
            if (depth == 0)
            {
                byte[] assetData;
                if (info.curFileType == 1)
                {
                    assetData = FixGameObjectFast(inst, info, field, (ulong)gidToMid[(long)info.index]);
                }
                else
                {
                    using (MemoryStream ms = new MemoryStream())
                        using (AssetsFileWriter w = new AssetsFileWriter(ms))
                        {
                            w.bigEndian = false;
                            field.Write(w);
                            assetData = ms.ToArray();
                        }
                }
                AssetID thisId = new AssetID(inst.name, (long)info.index);
                ids[thisId] = assetData;
            }
        }
Example #7
0
        private void LoadComponentData(PGProperty root, AssetTypeValueField baseField, AssetFileInfoEx info, int index, int size)
        {
            string className = AssetHelper.FindAssetClassByID(helper.classFile, info.curFileType)
                               .name.GetString(helper.classFile);
            AssetTypeValueField targetBaseField = baseField;

            if (className == "MonoBehaviour")
            {
                className += $" ({GetClassName(helper, inst, targetBaseField)})";
                string managedPath = Path.Combine(Path.GetDirectoryName(inst.path), "Managed");
                if (Directory.Exists(managedPath))
                {
                    targetBaseField = helper.GetMonoBaseFieldCached(inst, info, managedPath);
                }
            }
            string category = new string('\t', size - index) + className;

            PopulateDataGrid(targetBaseField, root, info, category);
        }
Example #8
0
        private static AssetsReplacerFromMemory MakeReplacer(ulong pathId, AssetsManager am, AssetsFileInstance file, AssetsFileInstance srcFile, AssetFileInfoEx inf, byte[] saData, List <Type_0D> types)
        {
            byte[] data = new byte[inf.curFileSize];
            //UnityEngine.Debug.Log("making rep for " + inf.absoluteFilePos + " => " + (inf.absoluteFilePos+inf.curFileSize) + " of " + file.stream.Length);
            int typeId = file.file.typeTree.pTypes_Unity5[inf.curFileTypeOrIndex].classId;

            if (!types.Any(t => t.classId == typeId) && !srcFile.file.typeTree.pTypes_Unity5.Any(t => t.classId == typeId))
            {
                if (!Hashes.hashes.ContainsKey(typeId))
                {
                    throw new NotImplementedException("hash not in hashtable, please add it!");
                }
                types.Add(new Type_0D()
                {
                    classId     = typeId,
                    unknown16_1 = 0,
                    scriptIndex = 0xFFFF,
                    unknown1    = 0,
                    unknown2    = 0,
                    unknown3    = 0,
                    unknown4    = 0,
                    unknown5    = Hashes.hashes[typeId][0],
                    unknown6    = Hashes.hashes[typeId][1],
                    unknown7    = Hashes.hashes[typeId][2],
                    unknown8    = Hashes.hashes[typeId][3]
                });
                //types.Add(C2T5.Cldb2TypeTree(am.classFile, typeId));
            }
            switch (typeId)
            {
            case 0x1C:
                data = FixTexture2D(am.GetATI(file.file, inf).GetBaseField(), saData);
                break;

            case 0x15:
                data = FixMaterial(srcFile.file, am.GetATI(file.file, inf).GetBaseField(), saData);
                break;

            default:
                file.stream.Position = (int)inf.absoluteFilePos;
                file.stream.Read(data, 0, (int)inf.curFileSize);
                break;
            }
            return(new AssetsReplacerFromMemory(0, pathId, typeId, 0xFFFF, data));
        }
Example #9
0
    public GameObject RecurseGameObjects(AssetFileInfoEx info, bool topRoot, bool hideOnCreation = false)
    {
        AssetTypeValueField gameObject = am.GetATI(assetsFile, info).GetBaseField();
        string name = gameObject.Get("m_Name").GetValue().AsString();
        AssetTypeValueField m_Component = gameObject.Get("m_Component").Get("Array");

        AssetsManager.AssetExternal transformComponent = am.GetExtAsset(assetsFileInstance, m_Component[0].Get("component"));
        AssetTypeValueField         transform          = transformComponent.instance.GetBaseField();

        if (name == "TileMap Render Data" || name == "Template-TileMap (1) Render Data") //should be .EndsWith(" Render Data")
        {
            return(TilemapRenderData(transform, name));
        }
        if (topRoot && transform.Get("m_Father").Get("m_PathID").GetValue().AsInt64() != 0)
        {
            return(null);
        }
        if (!topRoot && transform.Get("m_Father").Get("m_PathID").GetValue().AsInt64() == 0)
        {
            return(null);
        }
        GameObject gameObjectInstance = new GameObject(name);

        //if this object or parent object is mask
        bool isMask = hideOnCreation;

        int m_Tag = (ushort)gameObject.Get("m_Tag").GetValue().AsUInt();

        if (m_Tag >= 20000)
        {
            int tagIndex = m_Tag - 20000;
            gameObjectInstance.tag = UnityEditorInternal.InternalEditorUtility.tags[tagIndex];
        }
        else if (m_Tag != 0)
        {
            string[] tags = new[] { "Respawn", "Finished", "EditorOnly", "MainCamera", "Player", "GameController" };
            gameObjectInstance.tag = tags[m_Tag - 1];
        }
        gameObjectInstance.layer = (int)gameObject.Get("m_Layer").GetValue().AsUInt();
        EditDiffer differ = gameObjectInstance.AddComponent <EditDiffer>();

        differ.fileId     = 0;
        differ.pathId     = info.index;
        differ.origPathId = differ.pathId;

        Transform transformInstance = gameObjectInstance.transform;

        AssetTypeValueField m_LocalPosition = transform.Get("m_LocalPosition");
        AssetTypeValueField m_LocalRotation = transform.Get("m_LocalRotation");
        AssetTypeValueField m_LocalScale    = transform.Get("m_LocalScale");

        Vector3    localPosition = GetVector3(m_LocalPosition);
        Quaternion localRotation = GetQuaternion(m_LocalRotation);
        Vector3    localScale    = GetVector3(m_LocalScale);

        for (uint i = 1; i < m_Component.GetValue().AsArray().size; i++)
        {
            //faster to check for only info but also keeps us from reading
            //particle systems which tend to update literally every minor update
            //if we end up needing more types we can use typetree2cldb on an editor file
            AssetsManager.AssetExternal component = am.GetExtAsset(assetsFileInstance, m_Component[i].Get("component"), true);
            if (component.info.curFileType == SPRITERENDERER)
            {
                component = am.GetExtAsset(assetsFileInstance, m_Component[i].Get("component"));
                AssetTypeValueField baseField = component.instance.GetBaseField();
                AssetTypeValueField m_Sprite  = baseField.Get("m_Sprite");
                int  fileId = m_Sprite.Get("m_FileID").GetValue().AsInt();
                long pathId = m_Sprite.Get("m_PathID").GetValue().AsInt64();

                AssetsManager.AssetExternal sprite = am.GetExtAsset(assetsFileInstance, m_Sprite);
                if (sprite.info == null) //spriterenderer with no sprite lol
                {
                    continue;
                }

                AssetsFileInstance spriteInst;
                if (m_Sprite.Get("m_FileID").GetValue().AsInt() == 0)
                {
                    spriteInst = assetsFileInstance;
                }
                else
                {
                    spriteInst = assetsFileInstance.dependencies[m_Sprite.Get("m_FileID").GetValue().AsInt() - 1];
                }

                Sprite         spriteInstance = bundleAssets[assetMap[new AssetID(Path.GetFileName(spriteInst.path), pathId)]] as Sprite;
                SpriteRenderer sr             = gameObjectInstance.AddComponent <SpriteRenderer>();
                string[]       sortingLayers  = new[] { "Default", "Far BG 2", "Far BG 1", "Mid BG", "Immediate BG", "Actors", "Player", "Tiles", "MID Dressing", "Immediate FG", "Far FG", "Vignette", "Over", "HUD" };
                sr.sortingLayerName = sortingLayers[baseField.Get("m_SortingLayer").GetValue().AsInt()];
                sr.sortingOrder     = baseField.Get("m_SortingOrder").GetValue().AsInt();
                sr.sprite           = spriteInstance;

                AssetTypeValueField m_Materials = baseField.Get("m_Materials").Get("Array");
                if (m_Materials.GetValue().AsArray().size > 0)
                {
                    AssetTypeValueField m_Material = m_Materials[0];

                    int  matFileId = m_Material.Get("m_FileID").GetValue().AsInt();
                    long matPathId = m_Material.Get("m_PathID").GetValue().AsInt64();

                    AssetsFileInstance materialInst;
                    if (m_Material.Get("m_FileID").GetValue().AsInt() == 0)
                    {
                        materialInst = assetsFileInstance;
                    }
                    else
                    {
                        materialInst = assetsFileInstance.dependencies[matFileId - 1];
                    }
                    if (assetMap.ContainsKey(new AssetID(Path.GetFileName(materialInst.path), matPathId)))
                    {
                        Material mat = bundleAssets[assetMap[new AssetID(Path.GetFileName(materialInst.path), matPathId)]] as Material;
                        if (mat.shader.name != "Sprites/Lit") //honestly this shader confuses me. it is the only shader
                        {                                     //with no code and only references the generic material
                            sr.material = mat;
                        }
                        //else
                        //{
                        //    mat.shader = sr.sharedMaterial.shader;
                        //    sr.sharedMaterial = mat;
                        //}
                        if (mat.shader.name == "Hollow Knight/Grass-Default" || mat.shader.name == "Hollow Knight/Grass-Diffuse")
                        {
                            sr.sharedMaterial.SetFloat("_SwayAmount", 0f); //stops grass animation
                        }
                    }
                    //else
                    //{
                    //    Debug.Log("failed to find " + Path.GetFileName(materialInst.path) + "/" + matPathId + ".dat");
                    //}
                }
            }
            if (component.info.curFileType == MONOBEHAVIOUR)
            {
                component = am.GetExtAsset(assetsFileInstance, m_Component[i].Get("component"));
                AssetTypeValueField baseField = component.instance.GetBaseField();
                int monoTypeId = assetsFileInstance.file.typeTree.pTypes_Unity5[component.info.curFileTypeOrIndex].scriptIndex;
                if (!monoBehaviourIds.ContainsKey(monoTypeId))
                {
                    //map out the monobehaviour script indexes to their name for fast lookup
                    AssetTypeValueField         m_Script = baseField.Get("m_Script");
                    AssetsManager.AssetExternal script   = am.GetExtAsset(assetsFileInstance, m_Script);
                    string scriptName = script.instance.GetBaseField().Get("m_Name").GetValue().AsString();
                    monoBehaviourIds[monoTypeId] = scriptName;
                }
                if (monoBehaviourIds[monoTypeId] == "tk2dSprite")
                {
                    string managedPath = Path.Combine(Path.GetDirectoryName(assetsFileInstance.path), "Managed");
                    baseField = am.GetMonoBaseFieldCached(assetsFileInstance, component.info, managedPath);

                    AssetTypeValueField collection = baseField.Get("collection");
                    int _spriteId = baseField.Get("_spriteId").GetValue().AsInt();

                    int fileId = collection.Get("m_FileID").GetValue().AsInt();
                    //long pathId = collection.Get("m_PathID").GetValue().AsInt64();

                    AssetsManager.AssetExternal sprite = am.GetExtAsset(assetsFileInstance, collection);
                    if (sprite.info == null)
                    {
                        continue;
                    }

                    AssetsFileInstance  spriteFileInstance = assetsFileInstance.dependencies[fileId - 1];
                    AssetTypeValueField spriteBaseField    = am.GetMonoBaseFieldCached(spriteFileInstance, sprite.info, managedPath);

                    //this is a bad hack but it works for some reason so here it is
                    //the reason the pivot is being set and not the actual position
                    //is so we don't modify the values on the transform component
                    Texture2D image = spriteLoader.LoadTK2dSpriteNative(am, spriteBaseField, spriteFileInstance, _spriteId);

                    AssetTypeValueField boundsData = spriteBaseField.Get("spriteDefinitions")[(uint)_spriteId].Get("boundsData")[0];
                    float xOff = boundsData.Get("x").GetValue().AsFloat() * 100;
                    float yOff = boundsData.Get("y").GetValue().AsFloat() * 100;

                    Vector2        offset         = new Vector2((image.width / 2f - xOff) / image.width, (image.height / 2f - yOff) / image.height);
                    Sprite         spriteInstance = Sprite.Create(image, new Rect(0, 0, image.width, image.height), offset, 100f);
                    SpriteRenderer sr             = gameObjectInstance.AddComponent <SpriteRenderer>();
                    sr.sortingLayerName = "Default";
                    sr.sortingOrder     = 0;
                    sr.sprite           = spriteInstance;
                }
                else if (monoBehaviourIds[monoTypeId] == "PlayMakerFSM")
                {
                    //string managedPath = Path.Combine(Path.GetDirectoryName(assetsFileInstance.path), "Managed");
                    //baseField = am.GetMonoBaseFieldCached(assetsFileInstance, component.info, managedPath);

                    string fsmName = ReadFSMName(component.info, assetsFileInstance.file.reader);//baseField.Get("fsm").Get("name").GetValue().AsString();
                    if (fsmName == "remasker" || fsmName == "unmasker" || fsmName == "remasker_inverse" || fsmName == "Remove")
                    {
                        isMask = true;
                    }
                }
            }
        }

        transformInstance.localScale    = localScale;
        transformInstance.localPosition = localPosition;
        transformInstance.localRotation = localRotation;

        Renderer ren = gameObjectInstance.GetComponent <Renderer>();

        if (isMask && ren != null)
        {
            ren.enabled = false;
        }

        AssetTypeValueField childrenArray = transform.Get("m_Children").Get("Array");
        uint childrenCount = childrenArray.GetValue().AsArray().size;

        for (uint i = 0; i < childrenCount; i++)
        {
            AssetTypeValueField childTf = am.GetExtAsset(assetsFileInstance, childrenArray[i]).instance.GetBaseField();
            AssetFileInfoEx     childGo = am.GetExtAsset(assetsFileInstance, childTf.Get("m_GameObject")).info;
            RecurseGameObjects(childGo, false, isMask).transform.SetParent(transformInstance, false);
        }

        return(gameObjectInstance);
    }
 protected SerializingAssetReplacer(AssetsManager manager, AssetsFile assetsFile, AssetFileInfoEx asset)
 {
     this.manager    = manager;
     this.assetsFile = assetsFile;
     this.asset      = asset;
 }
Example #11
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());
                }
        }
 protected SerializingAssetReplacer(AssetsManager manager, AssetsFileInstance assetsFile, AssetFileInfoEx asset)
     : this(manager, assetsFile.file, asset)
 {
 }
Example #13
0
        private static bool EnableVROptions(string path)
        {
            AssetsManager      assetsManager      = new AssetsManager();
            AssetsFileInstance assetsFileInstance = assetsManager.LoadAssetsFile(path, false, "");

            assetsManager.LoadClassDatabase(Path.Combine(VREnabler.VRPatcherPath, "cldb.dat"));
            int num = 0;

            while ((long)num < (long)((ulong)assetsFileInstance.table.assetFileInfoCount))
            {
                try
                {
                    AssetFileInfoEx     assetInfo            = assetsFileInstance.table.GetAssetInfo((long)num);
                    AssetTypeInstance   ati                  = assetsManager.GetATI(assetsFileInstance.file, assetInfo, false);
                    AssetTypeValueField assetTypeValueField  = (ati != null) ? ati.GetBaseField(0) : null;
                    AssetTypeValueField assetTypeValueField2 = (assetTypeValueField != null) ? assetTypeValueField.Get("enabledVRDevices") : null;
                    if (assetTypeValueField2 != null)
                    {
                        AssetTypeValueField assetTypeValueField3 = assetTypeValueField2.Get("Array");
                        if (assetTypeValueField3 != null)
                        {
                            AssetTypeValueField assetTypeValueField4 = ValueBuilder.DefaultValueFieldFromArrayTemplate(assetTypeValueField3);
                            assetTypeValueField4.GetValue().Set("Oculus");
                            AssetTypeValueField assetTypeValueField5 = ValueBuilder.DefaultValueFieldFromArrayTemplate(assetTypeValueField3);
                            assetTypeValueField5.GetValue().Set("OpenVR");
                            AssetTypeValueField assetTypeValueField6 = ValueBuilder.DefaultValueFieldFromArrayTemplate(assetTypeValueField3);
                            assetTypeValueField6.GetValue().Set("None");
                            assetTypeValueField3.SetChildrenList(new AssetTypeValueField[]
                            {
                                assetTypeValueField6,
                                assetTypeValueField4,
                                assetTypeValueField5
                            });
                            byte[] array;
                            using (MemoryStream memoryStream = new MemoryStream())
                            {
                                using (AssetsFileWriter assetsFileWriter = new AssetsFileWriter(memoryStream))
                                {
                                    assetsFileWriter.bigEndian = false;
                                    AssetWriters.Write(assetTypeValueField, assetsFileWriter, 0);
                                    array = memoryStream.ToArray();
                                }
                            }
                            List <AssetsReplacer> list = new List <AssetsReplacer>
                            {
                                new AssetsReplacerFromMemory(0, (long)num, (int)assetInfo.curFileType, ushort.MaxValue, array)
                            };
                            using (MemoryStream memoryStream2 = new MemoryStream())
                            {
                                using (AssetsFileWriter assetsFileWriter2 = new AssetsFileWriter(memoryStream2))
                                {
                                    assetsFileInstance.file.Write(assetsFileWriter2, 0UL, list, 0U, null);
                                    assetsFileInstance.stream.Close();
                                    File.WriteAllBytes(path, memoryStream2.ToArray());
                                }
                            }
                            return(true);
                        }
                    }
                }
                catch
                {
                }
                num++;
            }
            VREnabler.Logger.LogError("VR enable location not found!");
            return(false);
        }
Example #14
0
        public static void GenerateDiffFile(AssetsManager am, AssetsFileInstance buildInst, AssetsFileInstance sceneInst, HKWEMeta meta)
        {
            EditorUtility.DisplayProgressBar("HKEdit", "Reading dependencies...", 0.5f);
            am.UpdateDependencies();

            ClassDatabaseFile cldb = am.classFile;

            DiffData result = new DiffData()
            {
                goChanges   = new List <GameObjectChange>(),
                goAdditions = new List <GameObjectAddition>()
            };

            Dictionary <EditDifferData, long> differToSceneId = new Dictionary <EditDifferData, long>();
            Dictionary <long, EditDifferData> buildIdToDiffer = new Dictionary <long, EditDifferData>();
            List <EditDifferData>             differData      = new List <EditDifferData>();

            AssetsFileTable        sceneTable = sceneInst.table;
            List <AssetFileInfoEx> sceneGos   = sceneTable.GetAssetsOfType(0x01);

            for (int i = 0; i < sceneGos.Count; i++)
            {
                if (i % 100 == 0)
                {
                    EditorUtility.DisplayProgressBar("HKEdit", "Finding diff IDs... (step 1/3)", (float)i / sceneGos.Count);
                }
                AssetFileInfoEx     inf       = sceneGos[i];
                AssetTypeValueField baseField = am.GetATI(sceneInst.file, inf).GetBaseField();

                AssetTypeValueField editDifferMono = GetEDMono(am, sceneInst, baseField);

                EditDifferData diff = new EditDifferData()
                {
                    fileId     = editDifferMono.Get("fileId").GetValue().AsInt(),
                    pathId     = editDifferMono.Get("pathId").GetValue().AsInt64(),
                    origPathId = editDifferMono.Get("origPathId").GetValue().AsInt64(),
                    newAsset   = editDifferMono.Get("newAsset").GetValue().AsBool()
                };

                buildIdToDiffer[diff.origPathId] = diff;
                differToSceneId[diff]            = inf.index;
                differData.Add(diff);
            }

            //////////////////////////

            AssetsFileTable        origTable = buildInst.table;
            List <AssetFileInfoEx> origGos   = origTable.GetAssetsOfType(0x01);

            List <long> origDeletIds = new List <long>();
            //int nextBundleId = 1;

            //// == delete changes == //
            //for (int i = 0; i < origGos.Count; i++)
            //{
            //    if (i % 100 == 0)
            //        EditorUtility.DisplayProgressBar("HKEdit", "Checking for deletes... (step 2/3)", (float)i / origGos.Count);
            //    AssetFileInfoEx inf = sceneGos[i];
            //    if (!differData.Any(d => d.origPathId == inf.index))
            //    {
            //        GameObjectChange change = new GameObjectChange
            //        {
            //            flags = GameObjectChangeFlags.Deleted
            //        };
            //        result.goChanges.Add(change);
            //        origDeletIds.Add(inf.index);
            //    }
            //}

            // == add changes == //
            //to get this working in a built game, we need
            //built assets (ie pngs -> texture2d) the problem
            //is there's no easy way to direct unity to do that
            //without loading the scene and using unity's api
            //but we can pull out assets into a prefab and build
            //the prefab but there are problems with duplicate
            //dependencies being copied, so we pack them all
            //into one place so that doesn't happen
            //(for reference, in hkwe1, each gameobject got
            //its own prefab)

            //find dependencies
            ReferenceCrawlerBundle createdCrawler  = new ReferenceCrawlerBundle(am); //assets created by the user in the ditor
            ReferenceCrawlerBundle existingCrawler = new ReferenceCrawlerBundle(am); //assets that already existed in the scene

            for (int i = 0; i < differData.Count; i++)
            {
                if (i % 100 == 0)
                {
                    EditorUtility.DisplayProgressBar("HKEdit", "Checking for additions... (step 2/3)", (float)i / differData.Count);
                }
                EditDifferData dat = differData[i];
                if (dat.newAsset)
                {
                    long            sceneId = differToSceneId[dat];
                    AssetFileInfoEx inf     = sceneInst.table.GetAssetInfo(sceneId);
                    createdCrawler.SetReferences(sceneInst, inf);
                    GameObjectAddition addition = new GameObjectAddition
                    {
                        bundleId     = createdCrawler.GetNextId(), //?
                        sceneId      = dat.pathId,
                        dependencies = new List <GameObjectAdditionDependency>()
                    };
                    //nextBundleId++;
                    foreach (KeyValuePair <AssetID, AssetID> goRef in createdCrawler.references)
                    {
                        addition.dependencies.Add(new GameObjectAdditionDependency
                        {
                            sceneId  = goRef.Key.pathId,
                            bundleId = goRef.Value.pathId
                        });
                    }
                    result.goAdditions.Add(addition);
                }
                else
                {
                    long            newPathId = differToSceneId[dat];
                    AssetFileInfoEx inf       = sceneInst.table.GetAssetInfo(newPathId);
                    existingCrawler.SetReferences(sceneInst, inf);
                }
            }

            //load up all created assets into a prefab
            List <Type_0D> types     = new List <Type_0D>();
            List <string>  typeNames = new List <string>();

            foreach (AssetsReplacer rep in createdCrawler.sceneReplacers)
            {
                ClassDatabaseType clType = AssetHelper.FindAssetClassByID(cldb, (uint)rep.GetClassID());
                string            clName = clType.name.GetString(cldb);
                if (!typeNames.Contains(clName))
                {
                    Type_0D type0d = C2T5.Cldb2TypeTree(cldb, clName);
                    type0d.classId = clType.classId;
                    types.Add(type0d);
                    typeNames.Add(clName);
                }
            }

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

            replacers.Add(CreatePrefabAsset(2)); //better hope id 2 is a gameobject
            replacers.AddRange(createdCrawler.sceneReplacers);

            AssetsFile createdFile = new AssetsFile(new AssetsFileReader(new MemoryStream(BundleCreator.CreateBlankAssets(ver, types))));

            byte[] data;
            using (MemoryStream ms = new MemoryStream())
                using (AssetsFileWriter writer = new AssetsFileWriter(ms))
                {
                    createdFile.Write(writer, 0, replacers, 0);
                    data = ms.ToArray();
                }
        }
Example #15
0
 public static AssetTypeInstance GetTypeInstanceNewData(this AssetsManager _this, AssetsFile file, AssetFileInfoEx info,
                                                        Stream data, bool forceFromCldb = false)
 {
     return(new AssetTypeInstance(_this.GetTemplateBaseField(file, info, forceFromCldb), new AssetsFileReader(data), 0));
 }
Example #16
0
        public static byte[] CreateBundleFromLevel(AssetsManager am, AssetsFileInstance inst)
        {
            AssetsFile      file  = inst.file;
            AssetsFileTable table = inst.table;

            string folderName = Path.GetDirectoryName(inst.path);

            ulong pathId = 2;
            List <AssetsReplacer>       assets   = new List <AssetsReplacer>();
            Dictionary <AssetID, ulong> assetMap = new Dictionary <AssetID, ulong>();

            //get all sprites

            int i = 0;
            List <AssetFileInfoEx> infos     = table.GetAssetsOfType(0xD4);
            List <ulong>           spriteIds = new List <ulong>();

            foreach (AssetFileInfoEx info in infos)
            {
                //honestly this is a really trash way to do this
                //we have a better scene exporter but it would
                //take some work to fix it up and block certain assets

                EditorUtility.DisplayProgressBar("HKEdit", "Creating scene bundle", i / (float)infos.Count);

                AssetTypeValueField baseField = GetBaseField(am, file, info);

                AssetTypeValueField m_Sprite   = baseField.Get("m_Sprite");
                AssetFileInfoEx     spriteInfo = am.GetExtAsset(inst, m_Sprite, true).info;
                AssetsFileInstance  spriteInst;
                if (m_Sprite.Get("m_FileID").GetValue().AsInt() == 0)
                {
                    spriteInst = inst;
                }
                else
                {
                    spriteInst = inst.dependencies[m_Sprite.Get("m_FileID").GetValue().AsInt() - 1];
                }

                int  spriteFileId = m_Sprite.Get("m_FileID").GetValue().AsInt();
                long spritePathId = m_Sprite.Get("m_PathID").GetValue().AsInt64();
                if (assetMap.ContainsKey(new AssetID(Path.GetFileName(spriteInst.path), spritePathId)) || (spriteFileId == 0 && spritePathId == 0))
                {
                    i++;
                    continue;
                }

                AssetTypeValueField spriteBaseField = GetBaseField(am, spriteInst.file, spriteInfo);

                AssetTypeValueField m_RD = spriteBaseField.Get("m_RD");

                AssetTypeValueField texture      = m_RD.Get("texture");
                AssetTypeValueField alphaTexture = m_RD.Get("alphaTexture");

                AssetsFileInstance textureInst, alphaTextureInst;
                if (texture.Get("m_FileID").GetValue().AsInt() == 0)
                {
                    textureInst = spriteInst;
                }
                else
                {
                    textureInst = spriteInst.dependencies[texture.Get("m_FileID").GetValue().AsInt() - 1];
                }

                if (alphaTexture.Get("m_FileID").GetValue().AsInt() == 0)
                {
                    alphaTextureInst = spriteInst;
                }
                else
                {
                    alphaTextureInst = spriteInst.dependencies[alphaTexture.Get("m_FileID").GetValue().AsInt() - 1];
                }

                AssetTypeInstance textureAti      = am.GetExtAsset(spriteInst, texture, false).instance;
                AssetTypeInstance alphaTextureAti = am.GetExtAsset(spriteInst, alphaTexture, false).instance;

                ulong textureId = 0, alphaTextureId = 0;

                if (textureAti != null)
                {
                    AssetID id = new AssetID(Path.GetFileName(textureInst.path), texture.Get("m_PathID").GetValue().AsInt64());
                    if (!assetMap.ContainsKey(id))
                    {
                        textureId = pathId;
                        assetMap.Add(id, pathId);
                        assets.Add(TextureConverter.ConvertTexture(textureAti.GetBaseField(), pathId++, folderName));
                    }
                    else
                    {
                        textureId = assetMap[id];
                    }
                }
                if (alphaTextureAti != null)
                {
                    AssetID id = new AssetID(Path.GetFileName(alphaTextureInst.path), alphaTexture.Get("m_PathID").GetValue().AsInt64());
                    if (!assetMap.ContainsKey(id))
                    {
                        alphaTextureId = pathId;
                        assetMap.Add(id, pathId);
                        assets.Add(TextureConverter.ConvertTexture(alphaTextureAti.GetBaseField(), pathId++, folderName));
                    }
                    else
                    {
                        alphaTextureId = assetMap[id];
                    }
                }
                AssetTypeValueField m_Materials = baseField.Get("m_Materials").Get("Array");
                if (m_Materials.GetValue().AsArray().size > 0)
                {
                    AssetTypeValueField material = baseField.Get("m_Materials").Get("Array")[0];
                    AssetsFileInstance  materialInst;

                    int materialFileId = material.Get("m_FileID").GetValue().AsInt();

                    if (materialFileId == 0)
                    {
                        materialInst = inst;
                    }
                    else
                    {
                        materialInst = inst.dependencies[materialFileId - 1];
                    }

                    AssetID materialId = new AssetID(Path.GetFileName(materialInst.path), material.Get("m_PathID").GetValue().AsInt64());
                    if (!assetMap.ContainsKey(materialId))
                    {
                        AssetTypeValueField materialBaseField = am.GetExtAsset(inst, material).instance.GetBaseField();

                        AssetTypeValueField shader = materialBaseField.Get("m_Shader");

                        ulong shaderPathId = RecurseShaderDependencies(am, materialInst, pathId, shader, assets, assetMap, out pathId);

                        assetMap.Add(materialId, pathId);
                        assets.Add(MaterialConverter.ConvertMaterial(materialBaseField, pathId++, shaderPathId));
                    }
                }

                assetMap.Add(new AssetID(Path.GetFileName(spriteInst.path), spritePathId), pathId);
                spriteIds.Add(pathId);
                assets.Add(SpriteConverter.ConvertSprite(spriteBaseField, pathId++, textureId, alphaTextureId));
                i++;
            }

            assetMap.Add(new AssetID(0), pathId);
            assets.Add(HeaderInformation.CreateHeaderInformation(assetMap, pathId++));

            assets.Insert(0, BundleMeta.CreateBundleInformation(assetMap, spriteIds, 1));
            //assets.Add(BundleMeta.CreateBundleInformation(assetMap, 1));

            //todo: pull from original assets file, cldb is not always update to date
            List <Type_0D> types = new List <Type_0D>
            {
                FixTypeTree(C2T5.Cldb2TypeTree(am.classFile, 0x8E)), //AssetBundle
                FixTypeTree(C2T5.Cldb2TypeTree(am.classFile, 0x1C)), //Texture2D
                FixTypeTree(C2T5.Cldb2TypeTree(am.classFile, 0x31)), //TextAsset
                FixTypeTree(C2T5.Cldb2TypeTree(am.classFile, 0xD4)), //SpriteRenderer
                FixTypeTree(C2T5.Cldb2TypeTree(am.classFile, 0xD5)), //Sprite
                //FixTypeTree(C2T5.Cldb2TypeTree(am.classFile, 0x31)), //TextAsset
                FixTypeTree(C2T5.Cldb2TypeTree(am.classFile, 0x15)), //Material
                FixTypeTree(C2T5.Cldb2TypeTree(am.classFile, 0x30))  //Shader
            };

            const string ver = "2017.4.10f1";

            //const string ver = "2018.2.1f1";

            byte[]     blankData = BundleCreator.CreateBlankAssets(ver, types);
            AssetsFile blankFile = new AssetsFile(new AssetsFileReader(new MemoryStream(blankData)));

            byte[] data = null;
            using (MemoryStream ms = new MemoryStream())
                using (AssetsFileWriter writer = new AssetsFileWriter(ms))
                {
                    blankFile.WriteFix(writer, 0, assets.ToArray(), 0);
                    data = ms.ToArray();
                }

            EditorUtility.DisplayProgressBar("HKEdit", "Creating bundle", 1);
            using (MemoryStream ms = new MemoryStream())
                using (AssetsFileWriter writer = new AssetsFileWriter(ms))
                {
                    BundleCreator.CreateBlankBundle(ver, data.Length).Write(writer, data);
                    return(ms.ToArray());
                }
        }
Example #17
0
        private void LoadFSMs(string path)
        {
            string folderName = Path.GetDirectoryName(path);

            curFile = am.LoadAssetsFile(path, true);
            am.UpdateDependencies();

            AssetsFile      file  = curFile.file;
            AssetsFileTable table = curFile.table;

            List <AssetInfo> assetInfos = new List <AssetInfo>();
            uint             assetCount = table.assetFileInfoCount;
            uint             fsmTypeId  = 0;

            foreach (AssetFileInfoEx info in table.pAssetFileInfo)
            {
                bool isMono = false;
                if (fsmTypeId == 0)
                {
                    ushort monoType = file.typeTree.pTypes_Unity5[info.curFileTypeOrIndex].scriptIndex;
                    if (monoType != 0xFFFF)
                    {
                        isMono = true;
                    }
                }
                else if (info.curFileType == fsmTypeId)
                {
                    isMono = true;
                }
                if (isMono)
                {
                    AssetTypeInstance monoAti   = am.GetATI(file, info);
                    AssetTypeInstance scriptAti = am.GetExtAsset(curFile, monoAti.GetBaseField().Get("m_Script")).instance;
                    AssetTypeInstance goAti     = am.GetExtAsset(curFile, monoAti.GetBaseField().Get("m_GameObject")).instance;
                    if (goAti == null) //found a scriptable object, oops
                    {
                        fsmTypeId = 0;
                        continue;
                    }
                    string m_Name      = goAti.GetBaseField().Get("m_Name").GetValue().AsString();
                    string m_ClassName = scriptAti.GetBaseField().Get("m_ClassName").GetValue().AsString();

                    if (m_ClassName == "PlayMakerFSM")
                    {
                        if (fsmTypeId == 0)
                        {
                            fsmTypeId = info.curFileType;
                        }

                        BinaryReader reader = file.reader;

                        long oldPos = reader.BaseStream.Position;
                        reader.BaseStream.Position  = (long)info.absoluteFilePos;
                        reader.BaseStream.Position += 28;
                        uint length = reader.ReadUInt32();
                        reader.ReadBytes((int)length);

                        long pad = 4 - (reader.BaseStream.Position % 4);
                        if (pad != 4)
                        {
                            reader.BaseStream.Position += pad;
                        }

                        reader.BaseStream.Position += 16;

                        uint   length2 = reader.ReadUInt32();
                        string fsmName = Encoding.ASCII.GetString(reader.ReadBytes((int)length2));
                        reader.BaseStream.Position = oldPos;

                        assetInfos.Add(new AssetInfo()
                        {
                            id   = info.index,
                            size = info.curFileSize,
                            name = m_Name + "-" + fsmName
                        });
                    }
                }
            }
            assetInfos.Sort((x, y) => x.name.CompareTo(y.name));
            FSMSelector selector = new FSMSelector(assetInfos);

            selector.ShowDialog();

            //todo separate into separate method(s)
            if (selector.selectedID == -1)
            {
                return;
            }

            AssetFileInfoEx afi = table.getAssetInfo((ulong)selector.selectedID);

            string  tabName = assetInfos.FirstOrDefault(i => i.id == (ulong)selector.selectedID).name;
            TabItem tab     = new TabItem
            {
                //Name = tabName.Replace(" ","").Replace("-","_").Replace("(","_").Replace(")","_"),
                Header = tabName
            };

            ignoreChangeEvent = true;
            fsmTabControl.Items.Add(tab);
            fsmTabControl.SelectedItem = tab;
            ignoreChangeEvent          = false;

            SaveAndClearNodes();
            mt.Matrix = Matrix.Identity;

            currentTab++;

            AssetTypeValueField baseField = am.GetMonoBaseFieldCached(curFile, afi, Path.Combine(Path.GetDirectoryName(curFile.path), "Managed"));

            //from uabe
            //ClassDatabaseType cldt = AssetHelper.FindAssetClassByID(am.classFile, afi.curFileType);
            //AssetTypeTemplateField pBaseField = new AssetTypeTemplateField();
            //pBaseField.FromClassDatabase(am.classFile, cldt, 0);
            //AssetTypeInstance mainAti = new AssetTypeInstance(1, new[] { pBaseField }, file.reader, false, afi.absoluteFilePos);
            //AssetTypeTemplateField[] desMonos;
            //desMonos = TryDeserializeMono(mainAti, am, folderName);
            //if (desMonos != null)
            //{
            //    AssetTypeTemplateField[] templateField = pBaseField.children.Concat(desMonos).ToArray();
            //    pBaseField.children = templateField;
            //    pBaseField.childrenCount = (uint)pBaseField.children.Length;
            //
            //    mainAti = new AssetTypeInstance(1, new[] { pBaseField }, file.reader, false, afi.absoluteFilePos);
            //}
            //AssetTypeValueField baseField = mainAti.GetBaseField();

            AssetTypeValueField fsm               = baseField.Get("fsm");
            AssetTypeValueField states            = fsm.Get("states");
            AssetTypeValueField globalTransitions = fsm.Get("globalTransitions");

            dataVersion = fsm.Get("dataVersion").GetValue().AsInt();
            for (int i = 0; i < states.GetValue().AsArray().size; i++)
            {
                AssetTypeValueField state = states.Get((uint)i);
                //move all of this into node
                string name = state.Get("name").GetValue().AsString();
                AssetTypeValueField rect = state.Get("position");
                Rect dotNetRect          = new Rect(rect.Get("x").GetValue().AsFloat(),
                                                    rect.Get("y").GetValue().AsFloat(),
                                                    rect.Get("width").GetValue().AsFloat(),
                                                    rect.Get("height").GetValue().AsFloat());
                AssetTypeValueField transitions   = state.Get("transitions");
                uint            transitionCount   = transitions.GetValue().AsArray().size;
                FsmTransition[] dotNetTransitions = new FsmTransition[transitionCount];
                for (int j = 0; j < transitionCount; j++)
                {
                    dotNetTransitions[j] = new FsmTransition(transitions.Get((uint)j));
                }
                Node node = new Node(state, name, dotNetRect, dotNetTransitions);
                nodes.Add(node);

                node.grid.MouseLeftButtonDown += (object sender, MouseButtonEventArgs e) =>
                {
                    foreach (Node node2 in nodes)
                    {
                        node2.Selected = false;
                    }
                    node.Selected = true;
                    SidebarData(node, curFile);
                };

                graphCanvas.Children.Add(node.grid);
            }
            for (int i = 0; i < globalTransitions.GetValue().AsArray().size; i++)
            {
                AssetTypeValueField transition = globalTransitions.Get((uint)i);

                FsmTransition dotNetTransition = new FsmTransition(transition);
                Node          toNode           = nodes.FirstOrDefault(n => n.name == dotNetTransition.toState);

                if (toNode == null)
                {
                    System.Diagnostics.Debug.WriteLine("transition " + dotNetTransition.fsmEvent.name + " going to non-existant node " + dotNetTransition.toState);
                }
                else
                {
                    Rect rect = new Rect(
                        toNode.Transform.X,
                        toNode.Transform.Y - 50,
                        toNode.Transform.Width,
                        18);

                    if (toNode != null)
                    {
                        Node node = new Node(null, dotNetTransition.fsmEvent.name, rect, new[] { dotNetTransition });
                        nodes.Add(node);

                        graphCanvas.Children.Add(node.grid);
                    }
                }
            }
            foreach (Node node in nodes)
            {
                if (node.transitions.Length <= 0)
                {
                    continue;
                }

                float yPos = 24;
                foreach (FsmTransition trans in node.transitions)
                {
                    Node endNode = nodes.FirstOrDefault(n => n.name == trans.toState);
                    if (endNode != null)
                    {
                        Point start, end, startMiddle, endMiddle;

                        if (node.state != null)
                        {
                            start = ComputeLocation(node, endNode, yPos, out bool isLeftStart);
                            end   = ComputeLocation(endNode, node, 10, out bool isLeftEnd);

                            double dist = 70;

                            if (isLeftStart == isLeftEnd)
                            {
                                dist *= 0.5;
                            }

                            if (!isLeftStart)
                            {
                                startMiddle = new Point(start.X - dist, start.Y);
                            }
                            else
                            {
                                startMiddle = new Point(start.X + dist, start.Y);
                            }

                            if (!isLeftEnd)
                            {
                                endMiddle = new Point(end.X - dist, end.Y);
                            }
                            else
                            {
                                endMiddle = new Point(end.X + dist, end.Y);
                            }
                        }
                        else
                        {
                            start = new Point(node.Transform.X + node.Transform.Width / 2,
                                              node.Transform.Y + node.Transform.Height);
                            end = new Point(endNode.Transform.X + endNode.Transform.Width / 2,
                                            endNode.Transform.Y);
                            startMiddle = new Point(start.X, start.Y + 1);
                            endMiddle   = new Point(end.X, end.Y - 1);
                        }


                        CurvedArrow arrow = new CurvedArrow()
                        {
                            Points = new PointCollection(new List <Point>()
                            {
                                start,
                                startMiddle,
                                endMiddle,
                                end
                            }),
                            StrokeThickness  = 2,
                            Stroke           = Brushes.Black,
                            Fill             = Brushes.Black,
                            IsHitTestVisible = true
                        };

                        arrow.MouseEnter += (object sender, MouseEventArgs e) =>
                        {
                            arrow.Stroke = Brushes.LightGray;
                            arrow.Fill   = Brushes.LightGray;
                        };

                        arrow.MouseLeave += (object sender, MouseEventArgs e) =>
                        {
                            arrow.Stroke = Brushes.Black;
                            arrow.Fill   = Brushes.Black;
                        };

                        Panel.SetZIndex(arrow, -1);

                        graphCanvas.Children.Add(arrow);
                    }
                    else
                    {
                        System.Diagnostics.Debug.WriteLine(node.name + " failed to connect to " + trans.toState);
                    }
                    yPos += 16;
                }
            }
            AssetTypeValueField events = fsm.Get("events");

            for (int i = 0; i < events.GetValue().AsArray().size; i++)
            {
                AssetTypeValueField @event = events.Get((uint)i);
                string name          = @event.Get("name").GetValue().AsString();
                bool   isSystemEvent = @event.Get("isSystemEvent").GetValue().AsBool();
                bool   isGlobal      = @event.Get("isGlobal").GetValue().AsBool();

                eventList.Children.Add(CreateSidebarRow(name, isSystemEvent, isGlobal));
            }
            AssetTypeValueField variables           = fsm.Get("variables");
            AssetTypeValueField floatVariables      = variables.Get("floatVariables");
            AssetTypeValueField intVariables        = variables.Get("intVariables");
            AssetTypeValueField boolVariables       = variables.Get("boolVariables");
            AssetTypeValueField stringVariables     = variables.Get("stringVariables");
            AssetTypeValueField vector2Variables    = variables.Get("vector2Variables");
            AssetTypeValueField vector3Variables    = variables.Get("vector3Variables");
            AssetTypeValueField colorVariables      = variables.Get("colorVariables");
            AssetTypeValueField rectVariables       = variables.Get("rectVariables");
            AssetTypeValueField quaternionVariables = variables.Get("quaternionVariables");
            AssetTypeValueField gameObjectVariables = variables.Get("gameObjectVariables");
            AssetTypeValueField objectVariables     = variables.Get("objectVariables");
            AssetTypeValueField materialVariables   = variables.Get("materialVariables");
            AssetTypeValueField textureVariables    = variables.Get("textureVariables");
            AssetTypeValueField arrayVariables      = variables.Get("arrayVariables");
            AssetTypeValueField enumVariables       = variables.Get("enumVariables");

            variableList.Children.Add(CreateSidebarHeader("Floats"));
            for (int i = 0; i < floatVariables.GetValue().AsArray().size; i++)
            {
                string name  = floatVariables.Get((uint)i).Get("name").GetValue().AsString();
                string value = floatVariables.Get((uint)i).Get("value").GetValue().AsFloat().ToString();
                variableList.Children.Add(CreateSidebarRow(name, value));
            }
            variableList.Children.Add(CreateSidebarHeader("Ints"));
            for (int i = 0; i < intVariables.GetValue().AsArray().size; i++)
            {
                string name  = intVariables.Get((uint)i).Get("name").GetValue().AsString();
                string value = intVariables.Get((uint)i).Get("value").GetValue().AsInt().ToString();
                variableList.Children.Add(CreateSidebarRow(name, value));
            }
            variableList.Children.Add(CreateSidebarHeader("Bools"));
            for (int i = 0; i < boolVariables.GetValue().AsArray().size; i++)
            {
                string name  = boolVariables.Get((uint)i).Get("name").GetValue().AsString();
                string value = boolVariables.Get((uint)i).Get("value").GetValue().AsBool().ToString().ToLower();
                variableList.Children.Add(CreateSidebarRow(name, value));
            }
            variableList.Children.Add(CreateSidebarHeader("Strings"));
            for (int i = 0; i < stringVariables.GetValue().AsArray().size; i++)
            {
                string name  = stringVariables.Get((uint)i).Get("name").GetValue().AsString();
                string value = stringVariables.Get((uint)i).Get("value").GetValue().AsString();
                variableList.Children.Add(CreateSidebarRow(name, value));
            }
            variableList.Children.Add(CreateSidebarHeader("Vector2s"));
            for (int i = 0; i < vector2Variables.GetValue().AsArray().size; i++)
            {
                string name = vector2Variables.Get((uint)i).Get("name").GetValue().AsString();
                AssetTypeValueField vector2 = vector2Variables.Get((uint)i).Get("value");
                string value = vector2.Get("x").GetValue().AsFloat().ToString() + ", ";
                value += vector2.Get("y").GetValue().AsFloat().ToString();
                variableList.Children.Add(CreateSidebarRow(name, value));
            }
            variableList.Children.Add(CreateSidebarHeader("Vector3s"));
            for (int i = 0; i < vector3Variables.GetValue().AsArray().size; i++)
            {
                string name = vector3Variables.Get((uint)i).Get("name").GetValue().AsString();
                AssetTypeValueField vector3 = vector3Variables.Get((uint)i).Get("value");
                string value = vector3.Get("x").GetValue().AsFloat().ToString() + ", ";
                value += vector3.Get("x").GetValue().AsFloat().ToString() + ", ";
                value += vector3.Get("z").GetValue().AsFloat().ToString();
                variableList.Children.Add(CreateSidebarRow(name, value));
            }
            variableList.Children.Add(CreateSidebarHeader("Colors"));
            for (int i = 0; i < colorVariables.GetValue().AsArray().size; i++)
            {
                string name = colorVariables.Get((uint)i).Get("name").GetValue().AsString();
                AssetTypeValueField color = colorVariables.Get((uint)i).Get("value");
                string value = ((int)(color.Get("r").GetValue().AsFloat()) * 255).ToString("X2");
                value += ((int)(color.Get("g").GetValue().AsFloat()) * 255).ToString("X2");
                value += ((int)(color.Get("b").GetValue().AsFloat()) * 255).ToString("X2");
                value += ((int)(color.Get("a").GetValue().AsFloat()) * 255).ToString("X2");
                Grid    sidebarRow = CreateSidebarRow(name, value);
                TextBox textBox    = sidebarRow.Children.OfType <TextBox>().FirstOrDefault();
                textBox.BorderBrush = (SolidColorBrush)(new BrushConverter().ConvertFrom("#" + value));
                variableList.Children.Add(sidebarRow);
            }
            variableList.Children.Add(CreateSidebarHeader("Rects"));
            for (int i = 0; i < rectVariables.GetValue().AsArray().size; i++)
            {
                string name = rectVariables.Get((uint)i).Get("name").GetValue().AsString();
                AssetTypeValueField rect = rectVariables.Get((uint)i).Get("value");
                string value             = rect.Get("x").GetValue().AsFloat().ToString() + ", ";
                value += rect.Get("y").GetValue().AsFloat().ToString() + ", ";
                value += rect.Get("width").GetValue().AsFloat().ToString() + ", ";
                value += rect.Get("height").GetValue().AsFloat().ToString();
                variableList.Children.Add(CreateSidebarRow(name, value));
            }
            variableList.Children.Add(CreateSidebarHeader("Quaternions"));
            for (int i = 0; i < quaternionVariables.GetValue().AsArray().size; i++)
            {
                string name = quaternionVariables.Get((uint)i).Get("name").GetValue().AsString();
                AssetTypeValueField rect = quaternionVariables.Get((uint)i).Get("value");
                string value             = rect.Get("x").GetValue().AsFloat().ToString() + ", ";
                value += rect.Get("y").GetValue().AsFloat().ToString() + ", ";
                value += rect.Get("z").GetValue().AsFloat().ToString() + ", ";
                value += rect.Get("w").GetValue().AsFloat().ToString();
                variableList.Children.Add(CreateSidebarRow(name, value));
            }
            variableList.Children.Add(CreateSidebarHeader("GameObjects"));
            for (int i = 0; i < gameObjectVariables.GetValue().AsArray().size; i++)
            {
                string name = gameObjectVariables.Get((uint)i).Get("name").GetValue().AsString();
                AssetTypeValueField gameObject = gameObjectVariables.Get((uint)i).Get("value");
                int  m_FileID = gameObject.Get("m_FileID").GetValue().AsInt();
                long m_PathID = gameObject.Get("m_PathID").GetValue().AsInt64();

                string value;
                if (m_PathID != 0)
                {
                    value = $"[{m_FileID},{m_PathID}]";
                }
                else
                {
                    value = "";
                }
                variableList.Children.Add(CreateSidebarRow(name, value));
            }
        }
Example #18
0
        public static AssetTypeValueField GetBaseField(AssetsManager am, AssetsFile file, AssetFileInfoEx info)
        {
            AssetTypeInstance ati = am.GetATI(file, info);

            return(ati.GetBaseField());
        }
Example #19
0
        //thats a nice function, be a shame if you ran out of memory
        private static void RecurseType(AssetsManager am, AssetsFileInstance inst, AssetFileInfoEx info, AssetTypeValueField field, List <string> fileNames, Dictionary <AssetID, byte[]> ids, int depth)
        {
            string p = new string(' ', depth);

            foreach (AssetTypeValueField child in field.pChildren)
            {
                //Console.WriteLine(p + child.templateField.type + " " + child.templateField.name);
                if (!child.templateField.hasValue)
                {
                    if (child == null)
                    {
                        return;
                    }
                    string typeName = child.templateField.type;
                    if (typeName.StartsWith("PPtr<") && typeName.EndsWith(">") && child.childrenCount == 2)
                    {
                        int  fileId = child.Get("m_FileID").GetValue().AsInt();
                        long pathId = child.Get("m_PathID").GetValue().AsInt64();

                        if (pathId == 0)
                        {
                            continue;
                        }

                        AssetsFileInstance depInst = null;
                        if (fileId == 0)
                        {
                            depInst = inst;
                        }
                        else
                        {
                            if (inst.dependencies.Count > 0 && inst.dependencies[0] == null)
                            {
                                Console.WriteLine("dependency null for " + inst.name);
                            }
                            depInst = inst.dependencies[fileId - 1];
                        }

                        string depName = depInst.name;
                        if (!fileNames.Contains(depName))
                        {
                            fileNames.Add(depName);
                        }

                        AssetID id = new AssetID(depInst.name, pathId);
                        if (!ids.ContainsKey(id))
                        {
                            AssetsManager.AssetExternal depExt  = am.GetExtAsset(inst, child);
                            AssetFileInfoEx             depInfo = depExt.info;

                            if (depInfo.curFileType == 1 ||
                                depInfo.curFileType == 4 ||
                                depInfo.curFileType == 21 ||
                                depInfo.curFileType == 23 ||
                                depInfo.curFileType == 28 ||
                                depInfo.curFileType == 33 ||
                                depInfo.curFileType == 43 ||
                                depInfo.curFileType == 48 ||
                                depInfo.curFileType == 212 ||
                                depInfo.curFileType == 213)
                            {
                                ids.Add(id, null);
                                AssetTypeValueField depBaseField;
                                if (depInfo.curFileType != 0x72)
                                {
                                    depBaseField = depExt.instance.GetBaseField();
                                }
                                else
                                {
                                    depBaseField = am.GetMonoBaseFieldCached(depExt.file, depInfo, Path.Combine(Path.GetDirectoryName(inst.path), "Managed"));
                                }

                                RecurseType(am, depInst, depInfo, depBaseField, fileNames, ids, 0);
                            }
                        }
                        //make fileId negative to mark for replacement
                        //we do the changes here since we're already iterating over each field
                        child.Get("m_FileID").GetValue().Set(-fileNames.IndexOf(depName));
                    }
                    RecurseType(am, inst, info, child, fileNames, ids, depth + 1);
                }
            }
            if (depth == 0)
            {
                byte[] assetData;
                if (info.curFileType == 28)
                {
                    assetData = FixTexture2DFast(inst, info);
                }
                else
                {
                    using (MemoryStream ms = new MemoryStream())
                        using (AssetsFileWriter w = new AssetsFileWriter(ms))
                        {
                            w.bigEndian = false;
                            field.Write(w);
                            assetData = ms.ToArray();
                        }
                }
                AssetID thisId = new AssetID(inst.name, (long)info.index);
                ids[thisId] = assetData;
            }
        }
Example #20
0
        public static void GenerateLevelFiles(AssetsManager am, AssetsFileInstance inst)
        {
            EditorUtility.DisplayProgressBar("HKEdit", "Reading dependencies...", 0.5f);
            am.UpdateDependencies();

            //quicker asset id lookup
            for (int i = 0; i < am.files.Count; i++)
            {
                AssetsFileInstance afi = am.files[i];
                if (i % 100 == 0)
                {
                    EditorUtility.DisplayProgressBar("HKEdit", "Generating QLTs...", (float)i / am.files.Count);
                }
                afi.table.GenerateQuickLookupTree();
            }

            ClassDatabaseFile cldb  = am.classFile;
            AssetsFileTable   table = inst.table;

            ReferenceCrawlerEditor crawler = new ReferenceCrawlerEditor(am);

            List <AssetFileInfoEx> initialGameObjects = table.GetAssetsOfType(0x01);

            for (int i = 0; i < initialGameObjects.Count; i++)
            {
                if (i % 100 == 0)
                {
                    EditorUtility.DisplayProgressBar("HKEdit", "Finding necessary assets... (step 1/3)", (float)i / initialGameObjects.Count);
                }
                AssetFileInfoEx inf = initialGameObjects[i];
                crawler.AddReference(new AssetID(inst.path, (long)inf.index), false);
                crawler.SetReferences(inst, inf);
            }

            Dictionary <AssetID, AssetID> glblToLcl = crawler.references;

            List <Type_0D> types     = new List <Type_0D>();
            List <string>  typeNames = new List <string>();

            Dictionary <string, AssetsFileInstance> fileToInst = am.files.ToDictionary(d => d.path);
            int j = 0;

            foreach (KeyValuePair <AssetID, AssetID> id in glblToLcl)
            {
                if (j % 100 == 0)
                {
                    EditorUtility.DisplayProgressBar("HKEdit", "Reordering path ids... (step 2/3)", (float)j / glblToLcl.Count);
                }
                AssetsFileInstance depInst = fileToInst[id.Key.fileName];
                AssetFileInfoEx    depInf  = depInst.table.GetAssetInfo(id.Key.pathId);

                ClassDatabaseType clType = AssetHelper.FindAssetClassByID(cldb, depInf.curFileType);
                string            clName = clType.name.GetString(cldb);
                if (!typeNames.Contains(clName))
                {
                    Type_0D type0d = C2T5.Cldb2TypeTree(cldb, clName);
                    type0d.classId = (int)depInf.curFileType;
                    types.Add(type0d);
                    typeNames.Add(clName);
                }

                crawler.ReplaceReferences(depInst, depInf, id.Value.pathId);
                j++;
            }

            EditorUtility.DisplayProgressBar("HKEdit", "Saving scene... (step 3/3)", 1f);

            types.Add(CreateEditDifferTypeTree(cldb));
            types.Add(CreateTk2dEmuTypeTree(cldb));

            List <Type_0D> assetTypes = new List <Type_0D>()
            {
                C2T5.Cldb2TypeTree(cldb, 0x1c),
                C2T5.Cldb2TypeTree(cldb, 0x30),
                C2T5.Cldb2TypeTree(cldb, 0x53),
                //new

                /*C2T5.Cldb2TypeTree(cldb, 0x5b),
                *  C2T5.Cldb2TypeTree(cldb, 0x4a),*/
                //C2T5.Cldb2TypeTree(cldb, 0x28f3fdef)
            };

            string origFileName = Path.GetFileNameWithoutExtension(inst.path);

            string sceneGuid = CreateMD5(origFileName);

            string ExportedScenes = Path.Combine("Assets", "ExportedScenes");
            //circumvents "!BeginsWithCaseInsensitive(file.pathName, AssetDatabase::kAssetsPathWithSlash)" assertion
            string ExportedScenesData = "ExportedScenesData";

            CreateMetaFile(sceneGuid, Path.Combine(ExportedScenes, origFileName + ".unity.meta"));

            AssetsFile sceneFile = new AssetsFile(new AssetsFileReader(new MemoryStream(BundleCreator.CreateBlankAssets(ver, types))));
            AssetsFile assetFile = new AssetsFile(new AssetsFileReader(new MemoryStream(BundleCreator.CreateBlankAssets(ver, assetTypes))));

            byte[] sceneFileData;
            using (MemoryStream ms = new MemoryStream())
                using (AssetsFileWriter w = new AssetsFileWriter(ms))
                {
                    w.bigEndian = false;
                    //unity editor won't load whole assets files by guid, so we have to use hardcoded paths
                    sceneFile.dependencies.dependencies = new List <AssetsFileDependency>()
                    {
                        CreateDependency(ExportedScenesData + "/" + origFileName + "-data.assets"),
                        CreateScriptDependency(Constants.editDifferMsEditorScriptHash, Constants.editDifferLsEditorScriptHash),
                        CreateScriptDependency(Constants.tk2dEmuMsEditorScriptHash, Constants.tk2dEmuLsEditorScriptHash),
                    };
                    sceneFile.dependencies.dependencyCount = 3;
                    sceneFile.preloadTable.items           = new List <AssetPPtr>()
                    {
                        new AssetPPtr(2, 11500000),
                        new AssetPPtr(3, 11500000)
                    };
                    sceneFile.preloadTable.len = 2;
                    sceneFile.Write(w, 0, crawler.sceneReplacers.Concat(crawler.sceneMonoReplacers).ToList(), 0);
                    sceneFileData = ms.ToArray();
                }
            byte[] assetFileData;
            using (MemoryStream ms = new MemoryStream())
                using (AssetsFileWriter w = new AssetsFileWriter(ms))
                {
                    w.bigEndian = false;
                    assetFile.dependencies.dependencies = new List <AssetsFileDependency>()
                    {
                        //CreateDependency("Assets/" + origFileName + ".unity"),
                    };
                    assetFile.dependencies.dependencyCount = 0;
                    assetFile.Write(w, 0, crawler.assetReplacers.ToList(), 0);
                    assetFileData = ms.ToArray();
                }

            File.WriteAllBytes(Path.Combine(ExportedScenes, origFileName + ".unity"), sceneFileData);
            File.WriteAllBytes(Path.Combine(ExportedScenesData, origFileName + "-data.assets"), assetFileData);
            File.WriteAllText(Path.Combine(ExportedScenesData, origFileName + ".metadata"), CreateHKWEMetaFile(am, inst));

            EditorUtility.ClearProgressBar();
        }
Example #21
0
        private void PopulateDataGrid(AssetTypeValueField atvf, PGProperty node, AssetFileInfoEx info, string category, bool arrayChildren = false)
        {
            if (atvf.childrenCount == 0)
            {
                return;
            }

            string arrayName = string.Empty;

            if (arrayChildren && atvf.childrenCount > 0)
            {
                arrayName = atvf.children[0].templateField.name;
            }

            for (int i = 0; i < atvf.childrenCount; i++)
            {
                AssetTypeValueField atvfc = atvf.children[i];
                if (atvfc == null)
                {
                    return;
                }

                string key;
                if (!arrayChildren)
                {
                    key = atvfc.GetName();
                }
                else
                {
                    key = $"{arrayName}[{i}]";
                }

                EnumValueTypes evt;
                if (atvfc.GetValue() != null)
                {
                    evt = atvfc.GetValue().GetValueType();
                    if (evt != EnumValueTypes.None)
                    {
                        if (1 <= (int)evt && (int)evt <= 12)
                        {
                            string     value = atvfc.GetValue().AsString();
                            PGProperty prop  = new PGProperty(key, value);
                            prop.category = category;
                            SetSelectedStateIfSelected(info, prop);
                            node.Add(prop);
                            PopulateDataGrid(atvfc, prop, info, category);
                        }
                        else if (evt == EnumValueTypes.Array)
                        {
                            PGProperty childProps = new PGProperty("child", null, $"[size: {atvfc.childrenCount}]");
                            PGProperty prop       = new PGProperty(key, childProps, $"[size: {atvfc.childrenCount}]");
                            prop.category = category;
                            SetSelectedStateIfSelected(info, prop);
                            node.Add(prop);
                            PopulateDataGrid(atvfc, childProps, info, category, true);
                        }
                        else if (evt == EnumValueTypes.ByteArray)
                        {
                            PGProperty childProps = new PGProperty("child", null, $"[bytes size: {atvfc.GetValue().AsByteArray().size}]");
                            PGProperty prop       = new PGProperty(key, childProps, $"[bytes size: {atvfc.GetValue().AsByteArray().size}]");
                            prop.category = category;
                            SetSelectedStateIfSelected(info, prop);
                            node.Add(prop);
                        }
                    }
                }
                else
                {
                    PGProperty childProps;
                    if (atvfc.childrenCount == 2)
                    {
                        AssetTypeValueField fileId = atvfc.children[0];
                        AssetTypeValueField pathId = atvfc.children[1];
                        string fileIdName          = fileId.templateField.name;
                        string fileIdType          = fileId.templateField.type;
                        string pathIdName          = pathId.templateField.name;
                        string pathIdType          = pathId.templateField.type;
                        if (fileIdName == "m_FileID" && fileIdType == "int" &&
                            pathIdName == "m_PathID" && pathIdType == "SInt64")
                        {
                            int  fileIdValue = fileId.GetValue().AsInt();
                            long pathIdValue = pathId.GetValue().AsInt64();
                            childProps = new PGProperty("child", "", $"[fileid: {fileIdValue}, pathid: {pathIdValue}]");
                        }
                        else
                        {
                            childProps = new PGProperty("child", "");
                        }
                    }
                    else
                    {
                        childProps = new PGProperty("child", "");
                    }
                    PGProperty prop = new PGProperty(key, childProps);
                    prop.category = category;
                    SetSelectedStateIfSelected(info, prop);
                    node.Add(prop);
                    PopulateDataGrid(atvfc, childProps, info, category);
                }
            }
        }
Example #22
0
 public static AssetsReplacer CreateAssetReplacer(AssetsFile file, AssetFileInfoEx info, byte[] data)
 {
     return(new AssetsReplacerFromMemory(0, info.index, (int)info.curFileType, AssetHelper.GetScriptIndex(file, info), data));
 }
Example #23
0
        private async void BtnImportDump_Click(object?sender, Avalonia.Interactivity.RoutedEventArgs e)
        {
            if (await FailIfNothingSelected())
            {
                return;
            }

            OpenFileDialog ofd = new OpenFileDialog();

            ofd.Title   = "Open";
            ofd.Filters = new List <FileDialogFilter>()
            {
                new FileDialogFilter()
                {
                    Name = "UABE text dump", Extensions = new List <string>()
                    {
                        "txt"
                    }
                },
                new FileDialogFilter()
                {
                    Name = "UABE json dump", Extensions = new List <string>()
                    {
                        "json"
                    }
                }
            };

            string[] fileList = await ofd.ShowAsync(this);

            if (fileList.Length == 0)
            {
                return;
            }

            string file = fileList[0];

            if (file != null && file != string.Empty)
            {
                if (file.EndsWith(".json"))
                {
                    await MessageBoxUtil.ShowDialog(this, "Not implemented", "There's no json dump support yet, sorry.");

                    return;
                }

                using (FileStream fs = File.OpenRead(file))
                    using (StreamReader sr = new StreamReader(fs))
                    {
                        AssetFileInfoEx selectedInfo = GetSelectedInfo();
                        long            selectedId   = selectedInfo.index;

                        AssetImportExport importer = new AssetImportExport();
                        byte[]? bytes = importer.ImportTextAsset(sr);

                        if (bytes == null)
                        {
                            await MessageBoxUtil.ShowDialog(this, "Parse error", "Something went wrong when reading the dump file.");

                            return;
                        }

                        AssetsReplacer replacer = AssetImportExport.CreateAssetReplacer(assetsFile.file, selectedInfo, bytes);
                        newAssets[selectedId]     = replacer;
                        newAssetDatas[selectedId] = new MemoryStream(bytes);

                        SetSelectedFieldModified();
                        modified = true;
                    }
            }
        }
Example #24
0
        public static string GetAssetNameFast(AssetsFile file, ClassDatabaseFile cldb, AssetFileInfoEx info)
        {
            ClassDatabaseType type = FindAssetClassByID(cldb, info.curFileType);

            AssetsFileReader reader = file.reader;

            if (type.fields.Count == 0)
            {
                return(type.name.GetString(cldb));
            }
            if (type.fields.Count > 1 && type.fields[1].fieldName.GetString(cldb) == "m_Name")
            {
                reader.Position = info.absoluteFilePos;
                return(reader.ReadCountStringInt32());
            }
            else if (type.name.GetString(cldb) == "GameObject")
            {
                reader.Position = info.absoluteFilePos;
                int size          = reader.ReadInt32();
                int componentSize = file.header.format > 0x10 ? 0xC : 0x10;
                reader.Position += size * componentSize;
                reader.Position += 4;
                return(reader.ReadCountStringInt32());
            }
            else if (type.name.GetString(cldb) == "MonoBehaviour")
            {
                reader.Position  = info.absoluteFilePos;
                reader.Position += 28;
                string name = reader.ReadCountStringInt32();
                if (name != "")
                {
                    return(name);
                }
            }
            return(type.name.GetString(cldb));
        }
Example #25
0
    private static void FinalizeAsset(AssetsFileInstance file, AssetTypeValueField field, AssetFileInfoEx info)
    {
        if (info.curFileType == 0x01) // GameObject
        {
            var ComponentArray = field.Get("m_Component").Get("Array");

            //remove all null pointers
            List <AssetTypeValueField> newFields = ComponentArray.pChildren.Where(f =>
                                                                                  f.pChildren[0].pChildren[1].GetValue().AsInt64() != 0
                                                                                  ).ToList();

            var newSize = (uint)newFields.Count;
            ComponentArray.SetChildrenList(newFields.ToArray(), newSize);
            ComponentArray.GetValue().Set(new AssetTypeArray()
            {
                size = newSize
            });
        }
        else if (info.curFileType == 0x73)     // MonoScript
        {
            var m_AssemblyName = field.Get("m_AssemblyName").GetValue();
            if (m_AssemblyName.AsString().Equals("Assembly-CSharp.dll"))
            {
                m_AssemblyName.Set("HKCode.dll");
            }
            else if (m_AssemblyName.AsString().Equals("Assembly-CSharp-firstpass.dll"))
            {
                m_AssemblyName.Set("HKCode-firstpass.dll");
            }
        }
        else if (info.curFileType == 0x1c)     // Texture2D
        {
            var path       = field.Get("m_StreamData").Get("path");
            var pathString = path.GetValue().AsString();
            var directory  = Path.GetDirectoryName(file.path);
            if (directory == null)
            {
                Debug.LogWarning("Texture2D has null stream data path!");
                return;
            }
            var fixedPath = Path.Combine(directory, pathString);
            path.GetValue().Set(fixedPath);
        }
        else if (info.curFileType == 0x53)     // AudioClip
        {
            var path       = field.Get("m_Resource").Get("m_Source");
            var pathString = path.GetValue().AsString();
            var directory  = Path.GetDirectoryName(file.path);
            if (directory == null)
            {
                Debug.LogWarning("AudioClip has null resource source path!");
                return;
            }
            var fixedPath = Path.Combine(directory, pathString);
            path.GetValue().Set(fixedPath);
        }
    }
Example #26
0
        public static void GenerateDiffFile(AssetsManager am, AssetsFileInstance origInst, AssetsFileInstance newInst, HKWEMeta meta)
        {
            EditorUtility.DisplayProgressBar("HKEdit", "Reading dependencies...", 0.5f);
            am.UpdateDependencies();

            DiffData result = new DiffData()
            {
                goChanges   = new List <GameObjectChange>(),
                goAdditions = new List <GameObjectAddition>()
            };

            Dictionary <EditDifferData, long> differToNewId  = new Dictionary <EditDifferData, long>();
            Dictionary <long, EditDifferData> origIdToDiffer = new Dictionary <long, EditDifferData>();
            List <EditDifferData>             differData     = new List <EditDifferData>();

            AssetsFileTable        newTable = newInst.table;
            List <AssetFileInfoEx> newGos   = newTable.GetAssetsOfType(0x01);

            for (int i = 0; i < newGos.Count; i++)
            {
                if (i % 100 == 0)
                {
                    EditorUtility.DisplayProgressBar("HKEdit", "Finding diff IDs... (step 1/3)", (float)i / newGos.Count);
                }
                AssetFileInfoEx     inf       = newGos[i];
                AssetTypeValueField baseField = am.GetATI(newInst.file, inf).GetBaseField();

                AssetTypeValueField editDifferMono = GetEDMono(am, newInst, baseField);

                EditDifferData diff = new EditDifferData()
                {
                    fileId     = editDifferMono.Get("fileId").GetValue().AsInt(),
                    pathId     = editDifferMono.Get("pathId").GetValue().AsInt64(),
                    origPathId = editDifferMono.Get("origPathId").GetValue().AsInt64(),
                    newAsset   = editDifferMono.Get("newAsset").GetValue().AsBool()
                };

                origIdToDiffer[diff.origPathId] = diff;
                differData.Add(diff);
            }

            //////////////////////////

            AssetsFileTable        origTable = origInst.table;
            List <AssetFileInfoEx> origGos   = origTable.GetAssetsOfType(0x01);

            List <long> origDeletIds = new List <long>();
            int         nextBundleId = 1;

            // == delete changes == //
            for (int i = 0; i < origGos.Count; i++)
            {
                if (i % 100 == 0)
                {
                    EditorUtility.DisplayProgressBar("HKEdit", "Checking for deletes... (step 2/3)", (float)i / origGos.Count);
                }
                AssetFileInfoEx inf = newGos[i];
                if (!differData.Any(d => d.origPathId == inf.index))
                {
                    GameObjectChange change = new GameObjectChange
                    {
                        flags = GameObjectChangeFlags.Deleted
                    };
                    result.goChanges.Add(change);
                    origDeletIds.Add(inf.index);
                }
            }

            // == add changes == //
            for (int i = 0; i < differData.Count; i++)
            {
                if (i % 100 == 0)
                {
                    EditorUtility.DisplayProgressBar("HKEdit", "Checking for additions... (step 2/3)", (float)i / differData.Count);
                }
                EditDifferData dat = differData[i];
                if (dat.newAsset)
                {
                    ReferenceCrawlerBundle crawler = new ReferenceCrawlerBundle(am);
                    long            newPathId      = differToNewId[dat];
                    AssetFileInfoEx inf            = newInst.table.GetAssetInfo(newPathId);
                    crawler.SetReferences(newInst, inf);
                    GameObjectAddition addition = new GameObjectAddition
                    {
                        bundleId     = nextBundleId,
                        parentId     = dat.pathId,
                        dependencies = new List <GameObjectAdditionDependency>()
                    };
                    nextBundleId++;
                    foreach (KeyValuePair <AssetID, AssetID> goRef in crawler.references)
                    {
                        addition.dependencies.Add(new GameObjectAdditionDependency
                        {
                            parentId = goRef.Key.pathId,
                            bundleId = goRef.Value.pathId
                        });
                    }
                    result.goAdditions.Add(addition);
                }
                else
                {
                    ReferenceCrawlerBundle crawler = new ReferenceCrawlerBundle(am);
                    long            newPathId      = differToNewId[dat];
                    AssetFileInfoEx inf            = newInst.table.GetAssetInfo(newPathId);
                    crawler.SetReferences(newInst, inf);
                }
            }
        }
Example #27
0
 // TODO: why does this only target three file types
 private static bool IsAsset(AssetFileInfoEx inf)
 {
     return(inf.curFileType == 0x1c || inf.curFileType == 0x30 || inf.curFileType == 0x53);
 }
        public static AssetTypeValueField GetMonoBaseField(AssetsManager am, AssetsFileInstance inst, AssetFileInfoEx info, string managedPath, bool cached = true)
        {
            AssetsFile             file      = inst.file;
            AssetTypeTemplateField baseField = new AssetTypeTemplateField();

            baseField.FromClassDatabase(am.classFile, AssetHelper.FindAssetClassByID(am.classFile, info.curFileType), 0);
            AssetTypeInstance mainAti     = new AssetTypeInstance(baseField, file.reader, info.absoluteFilePos);
            ushort            scriptIndex = AssetHelper.GetScriptIndex(file, info);

            if (scriptIndex != 0xFFFF)
            {
                AssetTypeInstance scriptAti       = am.GetExtAsset(inst, mainAti.GetBaseField().Get("m_Script")).instance;
                string            scriptName      = scriptAti.GetBaseField().Get("m_ClassName").GetValue().AsString();
                string            scriptNamespace = scriptAti.GetBaseField().Get("m_Namespace").GetValue().AsString();
                string            assemblyName    = scriptAti.GetBaseField().Get("m_AssemblyName").GetValue().AsString();
                string            assemblyPath    = Path.Combine(managedPath, assemblyName);

                if (scriptNamespace != string.Empty)
                {
                    scriptName = scriptNamespace + "." + scriptName;
                }

                if (File.Exists(assemblyPath))
                {
                    AssemblyDefinition asmDef;
                    if (cached)
                    {
                        if (!loadedAssemblies.ContainsKey(assemblyName))
                        {
                            loadedAssemblies.Add(assemblyName, GetAssemblyWithDependencies(assemblyPath));
                        }
                        asmDef = loadedAssemblies[assemblyName];
                    }
                    else
                    {
                        asmDef = GetAssemblyWithDependencies(assemblyPath);
                    }

                    MonoDeserializer mc = new MonoDeserializer();
                    mc.Read(scriptName, asmDef, new UnityVersion(inst.file.typeTree.unityVersion));
                    List <AssetTypeTemplateField> monoTemplateFields = mc.children;

                    AssetTypeTemplateField[] templateField = baseField.children.Concat(monoTemplateFields).ToArray();
                    baseField.children      = templateField;
                    baseField.childrenCount = baseField.children.Length;

                    mainAti = new AssetTypeInstance(baseField, file.reader, info.absoluteFilePos);
                }
            }
            return(mainAti.GetBaseField());
        }
Example #29
0
 public AssetTypeInstance GetTypeInstance(AssetsFileInstance inst, AssetFileInfoEx info, bool forceFromCldb = false)
 {
     return(GetTypeInstance(inst.file, info, forceFromCldb));
 }
Example #30
0
        private void LoadComponentData(PGProperty root, AssetTypeValueField baseField, AssetFileInfoEx info, int index, int size)
        {
            string className = AssetHelper.FindAssetClassByID(helper.classFile, info.curFileType)
                               .name.GetString(helper.classFile);
            AssetTypeValueField targetBaseField = baseField;

            if (className == "MonoBehaviour")
            {
                if (AssetUtils.AllDependenciesLoaded(helper, inst))
                {
                    className += $" ({GetClassName(helper, inst, targetBaseField)})";
                    string managedPath = Path.Combine(Path.GetDirectoryName(inst.path), "Managed");
                    if (Directory.Exists(managedPath))
                    {
                        targetBaseField = helper.GetMonoBaseFieldCached(inst, info, managedPath);
                    }
                }
                else if (!firstTimeMBMessage)
                {
                    firstTimeMBMessage = true;
                    MessageBox.Show("Can't display MonoBehaviour data until dependencies are loaded", "Assets View");
                }
            }
            string category = new string('\t', size - index) + className;

            RecursiveTreeLoad(targetBaseField, root, info, category);
        }