示例#1
0
        private static void LoadPrototype(ulong id)
        {
            string path      = String.Format("/resources/systemgenerated/prototypes/{0}.node", id);
            File   protoFile = Assets.FindFile(path);

            if (protoFile == null)
            {
                Console.WriteLine("Unable to find {0}", path);
            }

            using (var fs = protoFile.Open())
                using (var br = new GomBinaryReader(fs, Encoding.UTF8))
                {
                    // Check PROT
                    int magicNum = br.ReadInt32();
                    if (magicNum != 0x544F5250)
                    {
                        throw new InvalidOperationException(String.Format("{0} does not begin with PROT", path));
                    }

                    br.ReadInt32(); // Skip 4 bytes

                    var proto = (GomObject)prototypeLoader.Load(br);
                    proto.Checksum = (long)protoFile.FileInfo.Checksum;
                    DomTypeMap.Add(proto.Id, proto);
                    AddToNameLookup(proto);
                }
        }
示例#2
0
        private static void LoadPrototypes()
        {
            File prototypeList = Assets.FindFile("/resources/systemgenerated/prototypes.info");

            using (var fs = prototypeList.Open())
                using (var br = new GomBinaryReader(fs, Encoding.UTF8))
                {
                    // Check PINF
                    int magicNum = br.ReadInt32();
                    if (magicNum != 0x464E4950)
                    {
                        throw new InvalidOperationException("prototypes.info does not begin with PINF");
                    }

                    br.ReadInt32(); // Skip 4 bytes

                    int numPrototypes = (int)br.ReadNumber();
                    int protoLoaded   = 0;
                    for (var i = 0; i < numPrototypes; i++)
                    {
                        ulong protId = br.ReadNumber();
                        byte  flag   = br.ReadByte();

                        if (flag == 1)
                        {
                            LoadPrototype(protId);
                            protoLoaded++;
                        }
                    }

                    Console.WriteLine("Loaded {0} prototype files", protoLoaded);
                }
        }
示例#3
0
        public static GomType Load(GomBinaryReader reader, bool fromGom = true)
        {
            GomTypeId typeId = (GomTypeId)reader.ReadByte();

            GomTypeLoaders.IGomTypeLoader gomTypeLoader;
            if (!gomTypeLoaderMap.TryGetValue(typeId, out gomTypeLoader))
            {
                throw new InvalidOperationException(String.Format("Unknown GomType with Type ID {0}", (byte)typeId));
            }

            return(gomTypeLoader.Load(reader, fromGom));
        }
示例#4
0
        private static void LoadBucketFiles()
        {
            //var bucketFileName = BucketFiles[0];
            foreach (var bucketFileName in BucketFiles)
            {
                string path       = String.Format("/resources/systemgenerated/buckets/{0}", bucketFileName);
                File   bucketFile = Assets.FindFile(path);
                using (var fs = bucketFile.Open())
                    using (var br = new GomBinaryReader(fs, Encoding.UTF8))
                    {
                        br.ReadBytes(0x24); // Skip 24 header bytes

                        ReadAllItems(br, 0x24);
                    }
            }
        }
示例#5
0
        private static void LoadClientGom()
        {
            File gomFile = Assets.FindFile("/resources/systemgenerated/client.gom");

            using (var fs = gomFile.Open())
                using (var br = new GomBinaryReader(fs, Encoding.UTF8))
                {
                    // Check DBLB
                    int magicNum = br.ReadInt32();
                    if (magicNum != 0x424C4244)
                    {
                        throw new InvalidOperationException("client.gom does not begin with DBLB");
                    }

                    br.ReadInt32(); // Skip 4 bytes

                    ReadAllItems(br, 8);
                }
        }
示例#6
0
        private static void LoadBucketList()
        {
            File gomFile = Assets.FindFile("/resources/systemgenerated/buckets.info");

            using (var fs = gomFile.Open())
                using (var br = new GomBinaryReader(fs, Encoding.UTF8))
                {
                    br.ReadBytes(8); // Skip 8 header bytes

                    var c9 = br.ReadByte();
                    if (c9 != 0xC9)
                    {
                        throw new InvalidOperationException(String.Format("Unexpected character in buckets.info @ offset 0x8 - expected 0xC9 found {0:X2}", c9));
                    }

                    short numEntries = br.ReadInt16(Endianness.BigEndian);

                    for (var i = 0; i < numEntries; i++)
                    {
                        string fileName = br.ReadLengthPrefixString();
                        BucketFiles.Add(fileName);
                    }
                }
        }
示例#7
0
 public virtual object ReadItem(GomBinaryReader reader)
 {
     return(ReadData(reader));
 }
示例#8
0
 public abstract object ReadData(GomBinaryReader reader);
示例#9
0
        public virtual bool ConfirmType(GomBinaryReader reader)
        {
            byte typeByte = reader.ReadByte();

            return(typeByte == (byte)this.TypeId);
        }
示例#10
0
        public void Parse(GomBinaryReader reader)
        {
            switch (this.ValueType)
            {
            case TypedValueType.Null:
                this.Value = null;
                break;

            case TypedValueType.Int8:
            case TypedValueType.Int16:
            case TypedValueType.Int24:
            case TypedValueType.Int32:
            case TypedValueType.Int40:
            case TypedValueType.Int48:
            case TypedValueType.Int56:
            case TypedValueType.Int64:
            {
                int numBytesToRead = ((byte)this.ValueType) - 0xB0 + 1;
                this.Value = reader.ReadVariableWidthUInt64(numBytesToRead);
            }
            break;

            case TypedValueType.UnicodeString:
            {
                int strLen = (int)reader.ReadByte();
                if ((strLen >= 0xB0) && (strLen <= 0xB7))
                {
                    strLen = (int)reader.ReadVariableWidthUInt64(strLen - 0xB0 + 1);
                }

                byte[] charData = reader.ReadBytes((int)strLen * 2);
                this.Value = Encoding.Unicode.GetString(charData);
            }
            break;

            case TypedValueType.CString:
            {
                int strLen = (int)reader.ReadByte();
                if ((strLen >= 0xB0) && (strLen <= 0xB7))
                {
                    strLen = (int)reader.ReadVariableWidthUInt64(strLen - 0xB0 + 1);
                }

                byte[] charData = reader.ReadBytes(strLen);
                this.Value = Encoding.UTF8.GetString(charData);
            }
            break;

            case TypedValueType.Array:
            case TypedValueType.Array2:
            {
                int arrayLen = (int)reader.ReadByte();
                if ((arrayLen >= 0xB0) && (arrayLen <= 0xB7))
                {
                    arrayLen = (int)reader.ReadVariableWidthUInt64(arrayLen - 0xB0 + 1);
                }

                List <TypedValue> arrayValues = new List <TypedValue>(arrayLen);
                for (var i = 0; i < arrayLen; i++)
                {
                    var val = reader.ReadTypedValue();
                    arrayValues.Add(val);
                }
                this.Value = arrayValues;

                // Array type 2 has a trailing byte for some reason
                if (this.ValueType == TypedValueType.Array2)
                {
                    reader.ReadByte();
                }
            }
            break;

            case TypedValueType.BizarroFieldType:
            case TypedValueType.FieldType:
            {
                this.Value = reader.ReadGomType();
            }
            break;

            default:
                throw new InvalidOperationException(String.Format("Unexpected TypedValue Type: {0:X}", this.ValueType));
            }
        }
示例#11
0
        public void Load()
        {
            if (IsLoaded)
            {
                return;
            }
            if (IsUnloaded)
            {
                throw new InvalidOperationException("Cannot reload object once it's unloaded");
            }

            if ((NumGlommed > 0) || (ObjectSizeInFile > 0))
            {
                byte[] buffer;

                if (IsCompressed)
                {
                    int dataLen = 8 * NumGlommed + ObjectSizeInFile;
                    int maxLen  = dataLen + 8;
                    buffer = new byte[maxLen];

                    // Decompress DataBuffer
                    using (var ms = new System.IO.MemoryStream(DataBuffer))
                        using (var istream = new ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream(ms, new ICSharpCode.SharpZipLib.Zip.Compression.Inflater(false)))
                        {
                            int readBytes = istream.Read(buffer, 0, maxLen);
                            Zeroes = readBytes - dataLen;
                            //istream.Read(buffer, 0, 0xF);
                        }
                }
                else
                {
                    string      path      = String.Format("/resources/systemgenerated/prototypes/{0}.node", this.Id);
                    TorLib.File protoFile = TorLib.Assets.FindFile(path);
                    using (var fs = protoFile.Open())
                        using (var br = new GomBinaryReader(fs, Encoding.UTF8))
                        {
                            br.ReadBytes(NodeDataOffset);
                            buffer = br.ReadBytes(ObjectSizeInFile);
                            Zeroes = 0;
                        }
                }

                // Load data from decompressed buffer
                using (var ms = new System.IO.MemoryStream(buffer))
                    using (var br = new GomBinaryReader(ms))
                    {
                        ms.Position         = Zeroes;
                        this.GlommedClasses = new List <DomClass>();
                        for (var glomIdx = 0; glomIdx < NumGlommed; glomIdx++)
                        {
                            var glomClassId = br.ReadUInt64();
                            var glomClass   = DataObjectModel.Get <DomClass>(glomClassId);
                            this.GlommedClasses.Add(glomClass);
                        }

                        this._data = ScriptObjectReader.ReadObject(this.DomClass, br);
                    }

                //FirstBytes = buffer.Take(0xF).ToArray();
            }

            this.DataBuffer = null; // Since we're loaded, we don't need to hold on to the compressed data anymore
            IsLoaded        = true;
        }
示例#12
0
        private static void ReadAllItems(GomBinaryReader br, long offset)
        {
            while (true)
            {
                // Begin Reading Gom Definitions

                int defLength = br.ReadInt32();

                // Length == 0 means we've read them all!
                if (defLength == 0)
                {
                    break;
                }

                //short defFlags = br.ReadInt16();
                //int defType = (defFlags >> 3) & 0x7;
                byte[] defBuffer = new byte[defLength];
                int    defZero   = br.ReadInt32();  // 4 blank bytes
                ulong  defId     = br.ReadUInt64(); // 8-byte type ID
                short  defFlags  = br.ReadInt16();  // 16-bit flag field
                int    defType   = (defFlags >> 3) & 0x7;

                //var defData = br.ReadBytes(defLength - 6);
                var defData = br.ReadBytes(defLength - 18);
                Buffer.BlockCopy(defData, 0, defBuffer, 18, defData.Length);

                using (var memStream = new System.IO.MemoryStream(defBuffer))
                    using (var defReader = new GomBinaryReader(memStream, Encoding.UTF8))
                    {
                        DomTypeLoaders.IDomTypeLoader loader;
                        if (typeLoaderMap.TryGetValue(defType, out loader))
                        {
                            var domType = loader.Load(defReader);
                            domType.Id = defId;
                            DomTypeMap.Add(domType.Id, domType);

                            if (String.IsNullOrEmpty(domType.Name))
                            {
                                string storedTypeName;
                                if (StoredNameMap.TryGetValue(domType.Id, out storedTypeName))
                                {
                                    domType.Name = storedTypeName;
                                }
                            }

                            AddToNameLookup(domType);
                        }
                        else
                        {
                            throw new InvalidOperationException(String.Format("No loader for DomType 0x{1:X} as offset 0x{0:X}", offset, defType));
                        }
                    }

                // Read the required number of padding bytes
                int padding = ((8 - (defLength & 0x7)) & 0x7);
                if (padding > 0)
                {
                    br.ReadBytes(padding);
                }

                offset = offset + defLength + padding;
            }
        }
示例#13
0
 public bool ConfirmType(GomBinaryReader reader)
 {
     // Confirm the next bytes from the GomBinaryReader match this field's type
     return(GomType.ConfirmType(reader));
 }
示例#14
0
        private void Load()
        {
            // Version with String Tables as XML files
            //var path = String.Format("/resources/en-us/{0}.str", this.Fqn.Replace('.','/'));
            //var file = Assets.FindFile(path);
            //if (file == null) { throw new Exception("File not found"); }

            //using (var fs = file.Open())
            //{
            //    var xmlReader = XmlReader.Create(fs);
            //    var xdoc = XDocument.Load(xmlReader);
            //    var xroot = xdoc.Root;

            //    this.Version = xroot.Attribute("version").AsInt();
            //    this.OwnerFqn = (string)xroot.Attribute("owner");
            //    this.OwnerId = xroot.Attribute("ownerID").AsLong();
            //    this.Guid = xroot.Attribute("GUID").AsLong();
            //    this.Fqn = (string)xroot.Attribute("fqn");
            //    var results = from row in xdoc.Descendants("string") select LoadString(row);
            //    data = results.ToDictionary(k => k.Id, v => v);
            //}

            // Version with String Tables as nodes
            //var enUsPath = "en-us." + this.Fqn;
            //var file = DataObjectModel.GetObject(enUsPath);
            //if (file == null) { throw new Exception("StringTable not found"); }

            //var strings = file.Data.strTableVariantStrings as IDictionary<object, object>; // Map<enum, Map<int, string>>
            //var entries = (IDictionary<object,object>)strings.First(kvp => ((ScriptEnum)kvp.Key).ToString() == "MaleMale").Value;
            //data = new Dictionary<long, StringTableEntry>();
            //foreach (var kvp in entries)
            //{
            //    var entry = new StringTableEntry()
            //    {
            //        Id = (long)kvp.Key,
            //        Text = (string)kvp.Value
            //    };
            //    data[entry.Id] = entry;
            //}

            // Version with String Tables as unique file format contained in swtor_en-us_global_1.tor
            var path = String.Format("/resources/en-us/{0}.stb", this.Fqn.Replace('.', '/'));
            var file = TorLib.Assets.FindFile(path);

            if (file == null)
            {
                throw new Exception("File not found");
            }

            data = new Dictionary <long, StringTableEntry>();

            using (var fs = file.OpenCopyInMemory())
            {
                var br = new GomBinaryReader(fs);
                br.ReadBytes(3);
                int numStrings = br.ReadInt32();

                long streamPos = 0;

                for (var i = 0; i < numStrings; i++)
                {
                    var entryId      = br.ReadInt64();
                    var entry_8      = br.ReadInt16();
                    var entry_A      = br.ReadSingle();
                    var entryLength  = br.ReadInt32();
                    var entryOffset  = br.ReadInt32();
                    var entryLength2 = br.ReadInt32();

                    var entry = new StringTableEntry()
                    {
                        Id   = entryId,
                        Text = String.Empty
                    };

                    if (entryLength > 0)
                    {
                        streamPos   = fs.Position;
                        fs.Position = entryOffset;
                        entry.Text  = br.ReadFixedLengthString(entryLength);
                        fs.Position = streamPos;
                    }

                    data[entryId] = entry;
                }
            }
        }
示例#15
0
        public static GomObjectData ReadObject(DomClass domClass, GomBinaryReader reader)
        {
            GomObjectData result = new GomObjectData();
            IDictionary <string, object> resultDict = result.Dictionary;

            if (domClass != null)
            {
                resultDict["Script_Type"] = domClass;
            }
            else
            {
                resultDict["Script_Type"] = null;
            }

            resultDict["Script_TypeId"] = reader.ReadNumber();

            int numFields = (int)reader.ReadNumber();

            resultDict["Script_NumFields"] = numFields;

            ulong fieldId = 0;

            for (var i = 0; i < numFields; i++)
            {
                fieldId += reader.ReadNumber();
                DomField field     = DataObjectModel.Get <DomField>(fieldId);
                GomType  fieldType = null;
                if (field == null)
                {
                    // No idea what kind of field this is, so we'll skip it but we still need to read the data..
                    fieldType = GomTypeLoader.Load(reader, false);
                }
                else
                {
                    fieldType = field.GomType;

                    // Confirm the type matches
                    if (!field.ConfirmType(reader))
                    {
                        throw new InvalidOperationException("Unexpected field type for field " + field.Name);
                    }
                }

                // Read in the data
                object fieldValue = fieldType.ReadData(reader);

                // Save data to resulting script object
                string fieldName = null;
                if ((field != null) && (!String.IsNullOrEmpty(field.Name)))
                {
                    fieldName = field.Name;
                }
                else
                {
                    fieldName = DataObjectModel.GetStoredTypeName(fieldId);
                    if (fieldName == null)
                    {
                        fieldName = String.Format("field_{0:X8}", fieldId);
                    }
                }

                resultDict.Add(fieldName, fieldValue);
            }

            return(result);
        }