Ejemplo n.º 1
0
        public DownloadHandler(BinaryReader stream, BackgroundWorkerEx worker)
        {
            worker?.ReportProgress(0, "Loading \"download\"...");

            stream.Skip(2); // DL

            byte b1 = stream.ReadByte();
            byte b2 = stream.ReadByte();
            byte b3 = stream.ReadByte();

            int numFiles = stream.ReadInt32BE();

            short numTags = stream.ReadInt16BE();

            int numMaskBytes = (numFiles + 7) / 8;

            for (int i = 0; i < numFiles; i++)
            {
                MD5Hash key = stream.Read <MD5Hash>();

                //byte[] unk = stream.ReadBytes(0xA);
                stream.Skip(0xA);

                //var entry = new DownloadEntry() { Index = i, Unk = unk };
                var entry = new DownloadEntry()
                {
                    Index = i
                };

                DownloadData.Add(key, entry);

                worker?.ReportProgress((int)((i + 1) / (float)numFiles * 100));
            }

            for (int i = 0; i < numTags; i++)
            {
                DownloadTag tag  = new DownloadTag();
                string      name = stream.ReadCString();
                tag.Type = stream.ReadInt16BE();

                byte[] bits = stream.ReadBytes(numMaskBytes);

                for (int j = 0; j < numMaskBytes; j++)
                {
                    bits[j] = (byte)((bits[j] * 0x0202020202 & 0x010884422010) % 1023);
                }

                tag.Bits = new BitArray(bits);

                Tags.Add(name, tag);
            }
        }
Ejemplo n.º 2
0
        public DownloadHandler(BinaryReader stream, BackgroundWorkerEx worker)
        {
            worker?.ReportProgress(0, "Loading \"download\"...");

            stream.Skip(2); // DL

            byte b1 = stream.ReadByte();
            byte b2 = stream.ReadByte();
            byte b3 = stream.ReadByte();

            int numFiles = stream.ReadInt32BE();

            short numTags = stream.ReadInt16BE();

            int numMaskBytes = (numFiles + 7) / 8;

            for (int i = 0; i < numFiles; i++)
            {
                MD5Hash key = stream.Read<MD5Hash>();

                //byte[] unk = stream.ReadBytes(0xA);
                stream.Skip(0xA);

                //var entry = new DownloadEntry() { Index = i, Unk = unk };
                var entry = new DownloadEntry() { Index = i };

                DownloadData.Add(key, entry);

                worker?.ReportProgress((int)((i + 1) / (float)numFiles * 100));
            }

            for (int i = 0; i < numTags; i++)
            {
                DownloadTag tag = new DownloadTag();
                string name = stream.ReadCString();
                tag.Type = stream.ReadInt16BE();

                byte[] bits = stream.ReadBytes(numMaskBytes);

                for (int j = 0; j < numMaskBytes; j++)
                    bits[j] = (byte)((bits[j] * 0x0202020202 & 0x010884422010) % 1023);

                tag.Bits = new BitArray(bits);

                Tags.Add(name, tag);
            }
        }
Ejemplo n.º 3
0
        public OWRootHandler(BinaryReader stream, BackgroundWorkerEx worker, CASCHandler casc)
        {
            worker?.ReportProgress(0, "Loading \"root\"...");

            string str = Encoding.ASCII.GetString(stream.ReadBytes((int)stream.BaseStream.Length));

            string[] array = str.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);

            // need to figure out what to do with those apm files

            for (int i = 1; i < array.Length; i++)
            {
                string[] filedata = array[i].Split('|');

                if (Path.GetExtension(filedata[2]) == ".apm")
                {
                    // add apm file for dev purposes
                    ulong fileHash1 = Hasher.ComputeHash(filedata[2]);
                    RootData[fileHash1] = new RootEntry()
                    {
                        MD5 = filedata[0].ToByteArray(), Block = RootBlock.Empty
                    };

                    CASCFile.FileNames[fileHash1] = filedata[2];

                    // add files listed in apm file
                    byte[] md5 = filedata[0].ToByteArray();

                    EncodingEntry enc = casc.Encoding.GetEntry(md5);

                    using (BinaryReader s = new BinaryReader(casc.OpenFile(enc.Key)))
                    {
                        if (s != null)
                        {
                            // still need to figure out complete apm structure
                            // at start of file there's a lot of data that is same in all apm files
                            s.BaseStream.Position = 0xC;

                            uint count = s.ReadUInt32();

                            s.BaseStream.Position = 0x894;

                            // size of each entry seems to be 0x48 bytes (0x2C bytes unk data; int size; ulong unk; byte[16] md5)
                            for (int j = 0; j < count; j++)
                            {
                                s.BaseStream.Position += 0x2C; // skip unknown
                                int size = s.ReadInt32();      // size (matches size in encoding file)
                                s.BaseStream.Position += 8;    // skip unknown
                                byte[] md5_2 = s.ReadBytes(16);

                                EncodingEntry enc2 = casc.Encoding.GetEntry(md5_2);

                                if (enc2 == null)
                                {
                                    throw new Exception("enc2 == null");
                                }

                                string fakeName = Path.GetFileNameWithoutExtension(filedata[2]) + "/" + md5_2.ToHexString();

                                ulong fileHash = Hasher.ComputeHash(fakeName);
                                RootData[fileHash] = new RootEntry()
                                {
                                    MD5 = md5_2, Block = RootBlock.Empty
                                };

                                CASCFile.FileNames[fileHash] = fakeName;
                            }
                        }
                    }
                }
            }

            int current = 0;

            Func <string, LocaleFlags> tag2locale = (s) =>
            {
                LocaleFlags locale;

                if (Enum.TryParse(s, out locale))
                {
                    return(locale);
                }

                return(LocaleFlags.All);
            };

            foreach (var entry in casc.Encoding.Entries)
            {
                DownloadEntry dl = casc.Download.GetEntry(entry.Value.Key);

                if (dl != null)
                {
                    string fakeName = "unknown" + "/" + entry.Key[0].ToString("X2") + "/" + entry.Key.ToHexString();

                    var locales = dl.Tags.Where(tag => tag.Value.Type == 4).Select(tag => tag2locale(tag.Key));

                    LocaleFlags locale = LocaleFlags.None;

                    foreach (var loc in locales)
                    {
                        locale |= loc;
                    }

                    ulong fileHash = Hasher.ComputeHash(fakeName);
                    RootData.Add(fileHash, new RootEntry()
                    {
                        MD5 = entry.Key, Block = new RootBlock()
                        {
                            LocaleFlags = locale
                        }
                    });

                    CASCFile.FileNames[fileHash] = fakeName;
                }

                worker?.ReportProgress((int)(++current / (float)casc.Encoding.Count * 100));
            }
        }