Ejemplo n.º 1
0
        private GFFObject[] ReadList(long offset)
        {
            long pos = file.Position;

            file.Position = lioffset + offset;

            //read the size of the list
            byte[] buffer = new byte[DWORD_SIZE];
            file.Read(buffer, 0, buffer.Length);
            uint count = BitConverter.ToUInt32(buffer, 0);

            //read the elements of the list (each being 1 uint index into the struct array)
            buffer = new byte[DWORD_SIZE * count];
            file.Read(buffer, 0, buffer.Length);

            file.Position = pos;

            GFFObject[] structs = new GFFObject[count];
            for (int i = 0, j = 0; i < count; i++, j += DWORD_SIZE)
            {
                GFFStructDef def = ReadStruct(BitConverter.ToUInt32(buffer, j));
                structs[i] = new GFFObject(null, GFFObject.FieldType.Struct, def.structValue, def.structID);
            }

            return(structs);
        }
Ejemplo n.º 2
0
        public GFFLoader(Stream file)
        {
            this.file = file;

            //read the file type and version
            byte[] buffer = new byte[DWORD_SIZE * 14];
            file.Read(buffer, 0, DWORD_SIZE * 14);

            string filetype = Encoding.ASCII.GetString(buffer, 0, 4);
            string filever  = Encoding.ASCII.GetString(buffer, 4, 4);

            //get the offset to and number of structs in the file
            structoffset = BitConverter.ToUInt32(buffer, 8);
            structcount  = BitConverter.ToInt32(buffer, 12);

            //get the offset to and number of fields in the file
            fieldoffset = BitConverter.ToUInt32(buffer, 16);
            fieldcount  = BitConverter.ToInt32(buffer, 20);

            //get the offset to and number of labels in the file
            labeloffset = BitConverter.ToUInt32(buffer, 24);
            labelcount  = BitConverter.ToInt32(buffer, 28);

            //get the offset to and number of field data in the file
            fdoffset = BitConverter.ToUInt32(buffer, 32);
            fdcount  = BitConverter.ToInt32(buffer, 36);

            //get the offset to and number of field indices in the file
            fioffset = BitConverter.ToUInt32(buffer, 40);
            ficount  = BitConverter.ToInt32(buffer, 44);

            //get the offset to and number of list indices in the file
            lioffset = BitConverter.ToUInt32(buffer, 48);
            licount  = BitConverter.ToInt32(buffer, 52);

            //read the top level struct, recursively reading the file
            GFFStructDef def = ReadStruct(0);

            TopStruct = new GFFObject(null, GFFObject.FieldType.Struct, def.structValue, def.structID);
        }
Ejemplo n.º 3
0
        public object Serialize <T>()
        {
            Type objectType = typeof(T);

            // Creates an instance of "T" from this GFFObject
            // Will throw an exception if a field does not match
            // the class we are serializing into
            switch (Type)
            {
            case GFFObject.FieldType.Struct:
                T return_obj = (T)Activator.CreateInstance(objectType);

                Dictionary <string, GFFObject> dict = (Dictionary <string, GFFObject>)Value;
                HashSet <string> found = new HashSet <string>();

                foreach (FieldInfo p in objectType.GetFields(BindingFlags.Public | BindingFlags.Instance))
                {
                    // Check that the dictionary has this property
                    GFFAttribute attr = (GFFAttribute)p.GetCustomAttributes(typeof(GFFAttribute)).First();
                    string       name = attr.name;

                    if (!dict.ContainsKey(name))
                    {
                        if (name == "structid")
                        {
                            p.SetValue(return_obj, StructID);
                            continue;
                        }
                        else
                        {
                            //Debug.LogWarning("Key " + name + " not found");
                            continue;
                        }
                    }

                    found.Add(name);

                    // Create a generic serializer method based on the expected type of this field
                    GFFObject  obj        = dict[name];
                    MethodInfo serializer = obj.GetType().GetMethod("Serialize").MakeGenericMethod(p.FieldType);

                    // Invoke this serializer on the value dict[name]
                    object serialized = serializer.Invoke(dict[name], null);

                    // Set the value in the instance
                    try
                    {
                        p.SetValue(return_obj, serialized);
                    } catch (Exception e)
                    {
                        Debug.LogError("Failed to serialize value " + name + " of type " + serialized.GetType() + "; expected " + p.FieldType);
                        throw e;
                    }
                }

                //foreach (string k in dict.Keys)
                //{
                //    if (!found.Contains(k))
                //    {
                //        Debug.LogWarning("Did not serialize value " + k + " with type " + dict[k].Value.GetType().ToString());
                //    }
                //}

                return(return_obj);

            case GFFObject.FieldType.List:
                // This is made easier because any list is guaranteed to be of type
                // List<GFFObject> (and the objects are always structs, but that's
                // not actually important).
                Type listType = objectType.GetGenericArguments()[0];

                Type  newListType = typeof(List <>).MakeGenericType(new[] { listType });
                IList return_list = (IList)Activator.CreateInstance(newListType);

                GFFObject[] items = (GFFObject[])Value;
                foreach (GFFObject obj in items)
                {
                    MethodInfo serializer = obj.GetType().GetMethod("Serialize").MakeGenericMethod(listType);
                    object     serialized = serializer.Invoke(obj, null);

                    return_list.Add(serialized);
                }

                return(return_list);

            case GFFObject.FieldType.Byte:
            case GFFObject.FieldType.Char:
            case GFFObject.FieldType.Word:
            case GFFObject.FieldType.Short:
            case GFFObject.FieldType.DWord:
            case GFFObject.FieldType.Int:
            case GFFObject.FieldType.DWord64:
            case GFFObject.FieldType.Int64:
            case GFFObject.FieldType.Float:
            case GFFObject.FieldType.Double:
            case GFFObject.FieldType.CExoString:
            case GFFObject.FieldType.ResRef:
            case GFFObject.FieldType.CExoLocString:
            case GFFObject.FieldType.Void:
            case GFFObject.FieldType.Quaternion:
            case GFFObject.FieldType.Vector3:
                return(Value);

            default:
                throw new Exception("Could not serialize type " + Type.ToString());
            }
        }