Exemplo n.º 1
0
        public static GameObject[] Unpack(byte[] bytes, UABConfig config = null, List <ISerializer> serializers = null)
        {
            var unzipped         = Zipper.UnzipString(bytes);
            var dataDeserialized = UABSerializer.DeserializeValueType <UABPackage>(unzipped);

            return(Builder.Unpack(dataDeserialized, config, serializers));
        }
Exemplo n.º 2
0
        public static byte[] PackToBytes(GameObject[] objects, UABConfig config = null, List <ISerializer> serializers = null)
        {
            var package        = Builder.Pack(objects, config, serializers);
            var dataSerialized = UABSerializer.SerializeValueType(package);
            var zipped         = Zipper.ZipString(dataSerialized);

            return(zipped);
        }
Exemplo n.º 3
0
        public object Deserialize(object component, UABField[] data, List <ISerializer> serializers)
        {
            if (UABSerializer.HasProperties(component) == true)
            {
                var fields = component.GetType().GetAllProperties()
                             .Where(x => x.GetCustomAttributes(true).Any(a => a is System.ObsoleteAttribute) == false && x.CanWrite == true && UABSerializer.FilterProperties(x) == true).ToArray();
                //var fields = component.GetType().GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.SetProperty | System.Reflection.BindingFlags.Instance);
                //if (UnityEngine.UI.Windows.Constants.LOGS_ENABLED == true) UnityEngine.Debug.Log(component + " :: " + UABSerializer.HasProperties(component) + " :: " + fields.Length);
                for (int i = 0; i < data.Length; ++i)
                {
                    var fieldInfo = fields.FirstOrDefault(x => x.Name == data[i].name);
                    if (fieldInfo != null)
                    {
                        fieldInfo.SetValue(component, this.Unpack(component, fieldInfo.PropertyType, data[i], serializers), null);
                    }
                    else
                    {
                        if (UnityEngine.UI.Windows.Constants.LOGS_ENABLED == true)
                        {
                            UnityEngine.Debug.LogWarningFormat("Property with the name `{0}` was not found on property deserialization stage. Be sure you have no per-platform #ifdef directives in your scripts. Skipped.", data[i].name);
                        }
                    }
                }
            }
            else
            {
                var fields = component.GetType().GetAllFields();
                for (int i = 0; i < data.Length; ++i)
                {
                    var fieldInfo = fields.FirstOrDefault(x => x.Name == data[i].name);
                    if (fieldInfo != null)
                    {
                        fieldInfo.SetValue(component, this.Unpack(component, fieldInfo.FieldType, data[i], serializers));
                    }
                    else
                    {
                        if (UnityEngine.UI.Windows.Constants.LOGS_ENABLED == true)
                        {
                            UnityEngine.Debug.LogWarningFormat("Field with the name `{0}` was not found on field deserialization stage. Be sure you have no per-platform #ifdef directives in your scripts. Skipped.", data[i].name);
                        }
                    }
                }
            }

            return(component);
        }
Exemplo n.º 4
0
        public object Unpack(object container, System.Type fieldType, UABField fieldData, List <ISerializer> serializers)
        {
            for (int i = 0; i < serializers.Count; ++i)
            {
                var s = serializers[i];
                if ((s is IBinarySerializer) == false && s.IsValid(fieldData.serializatorId) == true)
                {
                    object obj = container;
                    s.DeserializeBeforeRef(this, fieldData, ref obj, serializers);
                    return(obj);
                }
            }

            object result = null;

            if (fieldData.fieldType == FieldType.ArrayType)
            {
                if (fieldData.fields == null)
                {
                    fieldData.fields = new UABField[0];
                }

                var elementType = fieldType.GetEnumerableType();
                if (fieldType.IsGenericType == true)
                {
                    IList list = (IList)System.Activator.CreateInstance(typeof(List <>).MakeGenericType(elementType));
                    for (int i = 0; i < fieldData.fields.Length; ++i)
                    {
                        var item = fieldData.fields[i];
                        if (item != null)
                        {
                            list.Add(this.Unpack(null, elementType, item, serializers));
                        }
                        else
                        {
                            list.Add(null);
                        }
                    }

                    result = list;
                }
                else if (fieldType.IsArray == true)
                {
                    var filledArray = System.Array.CreateInstance(elementType, fieldData.fields.Length);
                    for (int i = 0; i < fieldData.fields.Length; ++i)
                    {
                        var item = fieldData.fields[i];
                        if (item != null)
                        {
                            filledArray.SetValue(this.Unpack(null, elementType, item, serializers), i);
                        }
                        else
                        {
                            filledArray.SetValue(null, i);
                        }
                    }

                    result = filledArray;
                }
            }
            else if (fieldData.fieldType == FieldType.NestedType)
            {
                var    type     = fieldType;
                object instance = null;
                try {
                    instance = System.Activator.CreateInstance(type);
                } catch (System.Exception) {
                    instance = System.Runtime.Serialization.FormatterServices.GetUninitializedObject(type);
                }

                //fieldInfo.SetValue(obj, instance);
                result = instance;
                this.Deserialize(instance, fieldData.fields, serializers);
            }
            else if (fieldData.fieldType == FieldType.ValueType)
            {
                //if (UnityEngine.UI.Windows.Constants.LOGS_ENABLED == true) UnityEngine.Debug.Log(obj + " :: " + fieldInfo.Name + " = " + fieldData.data + " << " + fieldData.serializatorId);

                object value = null;

                var found = false;
                for (int i = 0; i < serializers.Count; ++i)
                {
                    if (serializers[i].IsValid(fieldData.serializatorId) == true)
                    {
                        object obj = container;
                        serializers[i].DeserializeBeforeRef(this, fieldData, ref obj, serializers);
                        value = obj;
                        found = true;
                        break;
                    }
                }

                if (found == false)
                {
                    // no custom serializator was found - use default
                    //fieldInfo.SetValue(obj, UABSerializer.DeserializeValueType(fieldData.data));

                    try {
                        if (fieldType.IsEnum == true)
                        {
                            value = System.Enum.ToObject(fieldType, int.Parse(fieldData.data));
                        }
                        else
                        {
                            value = System.Convert.ChangeType(fieldData.data, fieldType);
                        }
                    } catch (System.Exception) {
                        //if (UnityEngine.UI.Windows.Constants.LOGS_ENABLED == true) UnityEngine.Debug.LogException(ex);
                        value = UABSerializer.DeserializeValueType(fieldData.data, fieldType);
                    }
                }

                //fieldInfo.SetValue(obj, value);
                result = value;
            }
            else if (fieldData.fieldType == FieldType.ReferenceType)
            {
                // Unpack ref type
                //if (UnityEngine.UI.Windows.Constants.LOGS_ENABLED == true) UnityEngine.Debug.Log("Unpack ref type: " + fieldData.data);

                //UAB.Builder.RegisterReferenceUnpack(fieldData, fieldInfo, obj, contextCallback);

                var data = UABSerializer.DeserializeValueType(fieldData.data, typeof(UABReference)) as UABReference;
                if (data != null)
                {
                    if (data.isLocal == false)
                    {
                        var rf = UnityEngine.UI.Windows.WindowSystemResources.Load <ObjectReference>(data.instanceId);
                        if (rf != null)
                        {
                            //if (UnityEngine.UI.Windows.Constants.LOGS_ENABLED == true) UnityEngine.Debug.LogWarning("Resources.Load: " + rf + " :: " + data.instanceId + " :: " + container);
                            //fieldInfo.SetValue(container, rf.reference);
                            result = rf.reference;
                        }
                        else
                        {
                            if (UnityEngine.UI.Windows.Constants.LOGS_ENABLED == true)
                            {
                                UnityEngine.Debug.LogWarning(string.Format("Resource Reference was not found `{0}`.", data.instanceId));
                            }
                        }
                    }
                    else
                    {
                        if (data.instanceId != "0")
                        {
                            object obj = null;
                            Object value;
                            if (this.GetTempByInstanceID(data.instanceId, out value) == true)
                            {
                                if (data.isGameObject == true)
                                {
                                    obj = (object)((value as Transform).gameObject);
                                }
                                else
                                {
                                    obj = (object)value;
                                }

                                result = obj;
                            }
                            else
                            {
                                throw new UnityException(string.Format("Package malformed. Local reference `{0}` was not found.", data.instanceId));
                            }
                        }
                    }
                }
                else
                {
                    throw new UnityException("Package malformed. UABReference deserialization failed.");
                }
            }
            else if (fieldData.fieldType == FieldType.BinaryType)
            {
                var data = UABSerializer.DeserializeValueType(fieldData.data, typeof(UABBinary)) as UABBinary;
                if (data != null)
                {
                    var binHeader = this.GetBinaryHeader(data.instanceId);
                    if (binHeader != null)
                    {
                        var found = false;
                        for (int i = 0; i < serializers.Count; ++i)
                        {
                            if (serializers[i].IsValid(binHeader.field.serializatorId) == true)
                            {
                                object obj     = null;
                                var    binData = this.GetBinaryData(binHeader.binDataInstanceId);
                                if (binData != null)
                                {
                                    var field = new UABField();
                                    field.data   = binData.data;
                                    field.fields = binHeader.field.fields;
                                    serializers[i].DeserializeBeforeRef(this, field, ref obj, serializers);
                                    result = obj;
                                    found  = true;
                                }
                                break;
                            }
                        }

                        if (found == false)
                        {
                            throw new UnityException(string.Format("Package malformed. Serializer was not found by id `{0}`.", binHeader.field.serializatorId));
                        }
                    }
                    else
                    {
                        throw new UnityException(string.Format("Package malformed. Binary Header was not found by id `{0}`.", data.instanceId));
                    }
                }
                else
                {
                    throw new UnityException("Package malformed. UABBinary deserialization failed.");
                }
            }

            return(result);
        }
        public UABField Pack(string fieldName, System.Type fieldType, object value, List <ISerializer> serializers)
        {
            var uField = new UABField();

            uField.name      = fieldName;
            uField.fieldType = FieldType.ValueType;

            if (value == null || (value is Object && (value as Object) == null))
            {
                uField.data = null;
                return(uField);
            }

            if ((value is Object) == false)
            {
                for (int i = 0; i < serializers.Count; ++i)
                {
                    var s = serializers[i];
                    if ((s is IBinarySerializer) == false && s.IsValid(value) == true)
                    {
                        s.Serialize(this, uField, ref value, serializers);
                        return(uField);
                    }
                }
            }

            var type = fieldType;

            if (value.IsArray() == true)
            {
                // array
                uField.fieldType = FieldType.ArrayType;
            }
            else if (
                (type.IsClass == true || type.IsValueType == true) &&
                type.IsSerializable == true &&
                type.IsSimpleType() == false &&
                type.IsEnum == false)
            {
                // nested

                uField.fieldType = FieldType.NestedType;
                uField.fields    = this.Serialize(value, serializers);
            }
            else if (
                type.IsSimpleType() == true ||
                type.IsValueType == true ||
                type.IsEnum == true)
            {
                // value type
                uField.fieldType = FieldType.ValueType;
            }
            else
            {
                // ref type
                uField.fieldType = FieldType.ReferenceType;

                if (UAB.Builder.IsBinary(this.currentBundleName, value as Object) == true)
                {
                    // binary type
                    uField.fieldType = FieldType.BinaryType;
                }
            }

            if (uField.fieldType == FieldType.ValueType)
            {
                var found = false;
                for (int i = 0; i < serializers.Count; ++i)
                {
                    if (serializers[i].IsValid(value) == true)
                    {
                        serializers[i].Serialize(this, uField, ref value, serializers);
                        found = true;
                        break;
                    }
                }

                if (found == false)
                {
                    // no custom serializator was found - use default
                    uField.serializatorId = "-1";
                    if (value is string)
                    {
                        uField.data = (string)value;
                    }
                    else
                    {
                        uField.data = UABSerializer.SerializeValueType(value);
                    }
                }
            }
            else if (uField.fieldType == FieldType.ReferenceType)
            {
                //Debug.Log("Pack ref type: " + value);

                this.RegisterReferencePack(uField, value);
            }
            else if (uField.fieldType == FieldType.BinaryType)
            {
                this.RegisterBinaryPack(uField, value);
            }
            else if (uField.fieldType == FieldType.ArrayType)
            {
                var count      = 0;
                var enumerator = ((IEnumerable)value).GetEnumerator();
                while (enumerator.MoveNext() == true)
                {
                    ++count;
                }

                //Debug.Log("Pack arr type: " + count);
                if (count > 0)
                {
                    enumerator.Reset();
                    uField.fields = new UABField[count];
                    count         = 0;
                    while (enumerator.MoveNext() == true)
                    {
                        var element = enumerator.Current;
                        uField.fields[count] = (element == null ? null : this.Pack(null, element.GetType(), element, serializers));
                        ++count;
                    }
                }
            }

            return(uField);
        }
        public UABField[] Serialize(object component, bool forced, List <ISerializer> serializers)
        {
            var list = ListPool <UABField> .Get();

            if (UABSerializer.HasProperties(component) == true)
            {
                var fields = component.GetType().GetAllProperties()
                             .Where(x => x.GetCustomAttributes(true).Any(a => a is System.ObsoleteAttribute) == false && x.CanWrite == true && UABSerializer.FilterProperties(x) == true).ToArray();
                for (int i = 0; i < fields.Length; ++i)
                {
                    var field = fields[i];

                    var ignoreAttr = field.GetCustomAttributes(typeof(BundleIgnoreAttribute), inherit: true);
                    if ((ignoreAttr != null && ignoreAttr.Length != 0))
                    {
                        continue;
                    }

                    if (this.IsSkipped(fields[i].PropertyType) == true)
                    {
                        continue;
                    }

                    list.Add(this.Pack(fields[i].Name, fields[i].PropertyType, fields[i].GetValue(component, null), serializers));
                }
            }
            else
            {
                var fields = component.GetType().GetAllFields();
                for (int i = 0; i < fields.Length; ++i)
                {
                    var field = fields[i];

                    if (forced == false)
                    {
                        var attr = field.GetCustomAttributes(typeof(SerializeField), inherit: true);
                        if ((attr == null || attr.Length == 0) && field.IsPublic == false)
                        {
                            continue;
                        }
                    }

                    var ignoreAttr = field.GetCustomAttributes(typeof(BundleIgnoreAttribute), inherit: true);
                    if ((ignoreAttr != null && ignoreAttr.Length != 0))
                    {
                        continue;
                    }

                    if (this.IsSkipped(fields[i].FieldType) == true)
                    {
                        continue;
                    }

                    list.Add(this.Pack(fields[i].Name, fields[i].FieldType, fields[i].GetValue(component), serializers));
                }
            }

            var uFields = list.ToArray();

            ListPool <UABField> .Release(list);

            return(uFields);
        }
        public void BuildReferences(Transform root)
        {
            var list = this.tempReferencesPack;

            for (int i = 0; i < list.Count; ++i)
            {
                var uField = list[i].uField;
                var value  = list[i].value;

                var isObjectNull   = (value as UnityEngine.Object) == null;
                var instanceId     = Builder.GetInstanceID(value).ToString();
                var isLocal        = (isObjectNull == false ? Builder.GetRoot(value) == root : true);
                var isGameObject   = (value is GameObject);
                var postInstanceId = string.Empty;

                //Debug.Log(Builder.GetRoot(value) + " :: " + root);

                var resultInstanceId = string.Empty;

                if (isLocal == false && isObjectNull == false)
                {
                    // Add resource link
                                        #if UNITY_EDITOR
                    var source    = value as Object;
                    var assetPath = UnityEditor.AssetDatabase.GetAssetPath(source);

                    instanceId = UnityEditor.AssetDatabase.AssetPathToGUID(assetPath);

                    if (assetPath.StartsWith("Assets/") == false)
                    {
                        // Unity default resource
                        instanceId = "_" + value.GetType().FullName + "." + (value as Object).name;
                    }
                    else
                    {
                        var obj = UnityEditor.AssetDatabase.LoadAssetAtPath <Object>(assetPath);
                        if (obj != source)
                        {
                            if (obj is GameObject)
                            {
                                // Object is storing inside
                                // Finding local asset path
                                postInstanceId = ME.UAB.Extensions.EditorUtilities.GetLocalIdentfierInFile(source).ToString();
                            }
                            else
                            {
                                var allObjects   = UnityEditor.AssetDatabase.LoadAllAssetsAtPath(assetPath);
                                var objectInside = allObjects.FirstOrDefault(x => x.name == source.name);
                                if (objectInside != null)
                                {
                                    var index = System.Array.IndexOf(allObjects, objectInside);
                                    if (index >= 0)
                                    {
                                        instanceId     = string.Format("{0}_{1}", UnityEditor.AssetDatabase.AssetPathToGUID(assetPath), index);
                                        postInstanceId = "inner";
                                    }
                                    else
                                    {
                                        throw new UnityException(string.Format("Object with the name `{0}` was not found in `{1}`. Package cannot be processed.", objectInside.name, assetPath));
                                    }
                                }
                                else
                                {
                                    throw new UnityException(string.Format("Object was not found in `{0}`. Package cannot be processed.", assetPath));
                                }
                            }
                        }
                        else
                        {
                            postInstanceId = "root";
                        }
                    }

                    var localPath   = this.config.UAB_RESOURCES_PATH;
                    var projectPath = "Assets/" + localPath;

                    {                     // Creating `Resources` directory
                        var path = Application.dataPath + "/" + localPath;
                        if (System.IO.Directory.Exists(path) == false)
                        {
                            System.IO.Directory.CreateDirectory(path);
                            UnityEditor.AssetDatabase.ImportAsset(projectPath);
                        }
                    }

                    {                     // Creating asset by GUID
                        var guid = instanceId + "_" + postInstanceId;
                        var name = guid + ".asset";

                        ObjectReference reference = null;
                        var             fullPath  = projectPath + "/" + name;
                        if (System.IO.File.Exists(fullPath) == false)
                        {
                            reference = ME.UAB.Extensions.EditorUtilities.CreateAsset <ObjectReference>(name, projectPath);
                        }
                        else
                        {
                            reference = UnityEditor.AssetDatabase.LoadAssetAtPath <ObjectReference>(fullPath);
                        }

                        reference.reference = source;
                        UnityEditor.EditorUtility.SetDirty(reference);
                    }
                                        #endif

                    resultInstanceId = string.Format("{0}_{1}", instanceId, postInstanceId);
                }
                else
                {
                    if (isGameObject == true)
                    {
                        var go = (value as GameObject);
                        instanceId = Builder.GetInstanceID(go == null ? null : go.transform).ToString();
                    }

                    resultInstanceId = instanceId;
                }

                uField.serializatorId = "-2";
                uField.data           = UABSerializer.SerializeValueType(new UABReference()
                {
                    instanceId = resultInstanceId, isLocal = isLocal, isGameObject = isGameObject
                });
            }

            list.Clear();
        }
        public void BuildBinaries(ref UABBinaryHeader[] headers, ref UABBinaryData[] data, List <ISerializer> serializers)
        {
            var binData = ListPool <UABBinaryData> .Get();

            var binHeaders = ListPool <UABBinaryHeader> .Get();

            var list = this.tempBinariesPack;

            for (int i = 0; i < list.Count; ++i)
            {
                var uField = list[i].uField;
                var value  = list[i].value;

                var headerId = string.Empty;
                var found    = false;

                                #if UNITY_EDITOR
                var instanceId = UnityEditor.AssetDatabase.AssetPathToGUID(UnityEditor.AssetDatabase.GetAssetPath(value as Object));

                for (int j = 0; j < serializers.Count; ++j)
                {
                    if (serializers[j].IsValid(value) == true)
                    {
                        if (binData.Any(x => x.instanceId == instanceId) == false)
                        {
                            var f = new UABField();
                            serializers[j].Serialize(null, f, ref value, serializers);
                            binData.Add(new UABBinaryData()
                            {
                                instanceId = instanceId, data = f.data
                            });
                        }

                        var field = new UABField();
                        serializers[j].Serialize(this, field, ref value, serializers);

                        var header = new UABBinaryHeader()
                        {
                            binDataInstanceId = instanceId
                        };
                        header.instanceId = header.GetHashCode().ToString();
                        header.field      = field;

                        headerId = header.instanceId;

                        if (binHeaders.Any(x => x.instanceId == header.instanceId) == false)
                        {
                            binHeaders.Add(header);
                        }

                        found = true;

                        break;
                    }
                }
                                #endif

                uField.serializatorId = "-3";
                uField.data           = UABSerializer.SerializeValueType(new UABBinary()
                {
                    instanceId = headerId
                });

                if (found == false)
                {
                    throw new UnityException(string.Format("Binary Serializer was not found for type `{0}`. Package cannot be processed.", value.GetType().ToString()));
                }
            }
            list.Clear();

            data = binData.ToArray();
            ListPool <UABBinaryData> .Release(binData);

            headers = binHeaders.ToArray();
            ListPool <UABBinaryHeader> .Release(binHeaders);
        }