Beispiel #1
0
    public ICollection ReadICollection(System.Type collectionType, ES2Type type)
    {
        if (settings.encrypt)
        {
            return(ReadEncryptedICollection(collectionType, type));
        }

        var result = (IList)ES2Reflection.CreateGenericInstance(collectionType, type.type);

        reader.ReadByte();         // TODO: Remove this line on the next change to ES2 format.
        int count = reader.ReadInt32();

        for (int i = 0; i < count; i++)
        {
            result.Add(Read <object>(type));
        }
        return(result);
    }
Beispiel #2
0
    public static Key GetCollectionType(System.Type type)
    {
        if (!ES2Reflection.IsAssignableFrom(typeof(IEnumerable), type))
        {
            return(Key._Null);
        }

        if (type.IsArray)
        {
            return(Key._NativeArray);
        }

        // If it's not an array and doesn't have generic arguments, we don't consider it to be a collection.
        if (!ES2Reflection.IsGenericType(type))
        {
            return(Key._Null);
        }

        System.Type genericType = type.GetGenericTypeDefinition();

        if (genericType == typeof(Dictionary <,>))
        {
            return(Key._Dictionary);
        }
        else if (genericType == typeof(List <>))
        {
            return(Key._List);
        }
        else if (genericType == typeof(Queue <>))
        {
            return(Key._Queue);
        }
        else if (genericType == typeof(Stack <>))
        {
            return(Key._Stack);
        }
        if (genericType == typeof(HashSet <>))
        {
            return(Key._HashSet);
        }

        return(Key._Null);
    }
Beispiel #3
0
    public IDictionary ReadIDictionary(System.Type dictionaryType, ES2Type keyType, ES2Type valueType)
    {
        if (settings.encrypt)
        {
            return(ReadEncryptedIDictionary(dictionaryType, keyType, valueType));
        }
        var result = (IDictionary)ES2Reflection.CreateGenericInstance(dictionaryType, keyType.type, valueType.type);

        reader.ReadByte();         // TODO: Remove this line on the next change to ES2 format.
        reader.ReadByte();         // TODO: Remove this line on the next change to ES2 format.

        int count = reader.ReadInt32();

        for (int i = 0; i < count; i++)
        {
            result.Add(Read <System.Object>(keyType), Read <System.Object>(valueType));
        }
        return(result);
    }
Beispiel #4
0
    private void ReadVariableRecursive(ES2AutoSave autoSave, ES2AutoSaveVariableInfo variable, ES2Reader reader, object obj)
    {
        string variableID  = reader.reader.ReadString();
        int    endPosition = (int)reader.stream.Position;
        int    length      = reader.reader.ReadInt32();

        endPosition += length;

        // Read Type data
        ES2Keys.Key collectionType = (ES2Keys.Key)reader.reader.ReadByte();
        int         typeHash       = reader.reader.ReadInt32();
        int         dictValueHash  = 0;

        if (collectionType == ES2Keys.Key._Dictionary)
        {
            dictValueHash = reader.reader.ReadInt32();
        }

        ES2AutoSaveVariableInfo info = autoSave.GetCachedVariableInfo(variableID);

        if (info == null)
        {
            reader.stream.Position = endPosition;
            return;
        }

        string dataType = reader.reader.ReadString();

        if (dataType == "data")
        {
            // Get ES2Types.
            ES2Type type          = ES2TypeManager.GetES2Type(typeHash);
            ES2Type dictValueType = null;
            if (collectionType == ES2Keys.Key._Dictionary)
            {
                dictValueType = ES2TypeManager.GetES2Type(dictValueHash);
            }

            // If the type of data we're loading isn't supported, skip it.
            if (type == null || (collectionType == ES2Keys.Key._Dictionary && dictValueType == null))
            {
                reader.stream.Position = endPosition;
                return;
            }

            bool valueWasSet = false;

            if (collectionType == ES2Keys.Key._Null)
            {
                valueWasSet = ES2Reflection.SetValue(obj, info.name, reader.Read <System.Object>(type), info.isProperty);
            }
            else if (collectionType == ES2Keys.Key._NativeArray)
            {
                valueWasSet = ES2Reflection.SetValue(obj, info.name, reader.ReadSystemArray(type), info.isProperty);
            }
            else if (collectionType == ES2Keys.Key._List)
            {
                valueWasSet = ES2Reflection.SetValue(obj, info.name, reader.ReadICollection(typeof(List <>), type), info.isProperty);
            }
            else if (collectionType == ES2Keys.Key._Queue)
            {
                valueWasSet = ES2Reflection.SetValue(obj, info.name, reader.ReadICollection(typeof(Queue <>), type), info.isProperty);
            }
            else if (collectionType == ES2Keys.Key._Stack)
            {
                valueWasSet = ES2Reflection.SetValue(obj, info.name, reader.ReadICollection(typeof(Stack <>), type), info.isProperty);
            }
            else if (collectionType == ES2Keys.Key._HashSet)
            {
                valueWasSet = ES2Reflection.SetValue(obj, info.name, reader.ReadICollection(typeof(HashSet <>), type), info.isProperty);
            }
            else if (collectionType == ES2Keys.Key._Dictionary)
            {
                valueWasSet = ES2Reflection.SetValue(obj, info.name, reader.ReadIDictionary(typeof(Dictionary <,>), type, dictValueType), info.isProperty);
            }

            if (!valueWasSet)
            {
                reader.stream.Position = endPosition;
                return;
            }
        }
        // Else, we have variables to load.
        else if (dataType == "vars")
        {
            object thisObj = ES2Reflection.GetValue(obj, info.name, info.isProperty);
            if (thisObj == null)
            {
                reader.stream.Position = endPosition;
            }
            ReadVariableRecursive(autoSave, info, reader, thisObj);
        }
        else
        {
            reader.stream.Position = endPosition;
            return;
        }
    }
Beispiel #5
0
    private void WriteVariableRecursive(ES2AutoSave autoSave, ES2AutoSaveVariableInfo variable, ES2Writer writer, object obj)
    {
        // Get the Type data for this variable, or return if a type is not supported.
        ES2Type es2Type       = null;
        ES2Type dictValueType = null;

        ES2Keys.Key collectionType = ES2Keys.GetCollectionType(variable.type);

        // If it's not a collection type, just get the basic ES2Type.
        if (collectionType == ES2Keys.Key._Null)
        {
            es2Type = ES2TypeManager.GetES2Type(variable.type);
        }
        // Otherwise, get the collection element types.
        else
        {
            if (collectionType == ES2Keys.Key._NativeArray)            // Get Array Element Type.
            {
                es2Type = ES2TypeManager.GetES2Type(variable.type.GetElementType());
            }
            else
            {
                // Get ES2Types for generic type arguments.
                Type[] genericArgs = ES2Reflection.GetGenericArguments(variable.type);
                if (genericArgs.Length > 0)
                {
                    es2Type = ES2TypeManager.GetES2Type(genericArgs[0]);
                    if (genericArgs.Length > 1)
                    {
                        dictValueType = ES2TypeManager.GetES2Type(genericArgs[1]);
                        if (dictValueType == null)
                        {
                            return;
                        }
                    }
                }
            }
        }

        // Skip if unsupported. Enums are not supported unless they have an explicit ES2Type.
        if (es2Type == null || es2Type.GetType() == typeof(ES2_Enum))
        {
            return;
        }

        writer.writer.Write(variable.id);
        int startPosition = writer.WritePropertyPrefix();

        // Write the Type data for this variable.
        writer.writer.Write((byte)collectionType);
        writer.writer.Write(es2Type.hash);
        // If Dictionary, also write the Dictionary value type.
        if (dictValueType != null)
        {
            writer.writer.Write(dictValueType.hash);
        }

        int variableCount = 0;

        foreach (string variableID in variable.variableIDs)
        {
            ES2AutoSaveVariableInfo variableInfo = autoSave.GetCachedVariableInfo(variableID);
            if (variableInfo.buttonSelected)
            {
                variableCount++;
                if (variableCount == 1)
                {
                    writer.writer.Write("vars");
                }

                object variableObj = ES2Reflection.GetValue(obj, variableInfo.name, variableInfo.isProperty);

                WriteVariableRecursive(autoSave, variableInfo, writer, variableObj);
            }
        }

        // If no variables were written, we want to save this variable.
        if (variableCount == 0)
        {
            writer.writer.Write("data");
            if (collectionType == ES2Keys.Key._Null)
            {
                writer.Write(obj, es2Type);
            }
            else if (collectionType == ES2Keys.Key._NativeArray)
            {
                writer.WriteSystemArray((Array)obj, es2Type);
            }
            else if (collectionType == ES2Keys.Key._List)
            {
                writer.WriteICollection((ICollection)obj, es2Type);
            }
            else if (collectionType == ES2Keys.Key._Queue)
            {
                writer.WriteICollection((ICollection)obj, es2Type);
            }
            else if (collectionType == ES2Keys.Key._Stack)
            {
                writer.WriteICollection((ICollection)obj, es2Type);
            }
            else if (collectionType == ES2Keys.Key._HashSet)
            {
                writer.WriteICollection((ICollection)obj, es2Type);
            }
            else if (collectionType == ES2Keys.Key._Dictionary)
            {
                writer.WriteIDictionary((IDictionary)obj, es2Type, dictValueType);
            }
        }

        writer.WritePropertyLength(startPosition);
    }