예제 #1
0
파일: GMDv1.cs 프로젝트: LITTOMA/Kuriimu
        public void Save(string filename, Platform platform, Game game)
        {
            //Get Text Section
            var TextBlob = Encoding.UTF8.GetBytes(GMDContent.Content.Aggregate("", (output, c) => output + c.Text.Replace("\r\n", "\xa").Replace("\xa", "\r\n") + "\0"));

            //XOR, if needed
            if (platform == Platform.CTR && game == Game.DD)
            {
                TextBlob = new BinaryReaderX(XOR.ReXOR(TextBlob, 0)).ReadAllBytes();
            }

            //Get Label Blob
            var LabelBlob = Encoding.ASCII.GetBytes(GMDContent.Content.Aggregate("", (output, c) => output + (c.Name.Contains("no_name") ? "" : c.Name + "\0")));

            //Create LabelEntries
            var Entries     = new List <LabelEntry>();
            var LabelOffset = 0;
            var LabelCount  = GMDContent.Content.Count(c => !c.Name.Contains("no_name"));

            for (int i = 0; i < GMDContent.Content.Count(); i++)
            {
                if (!GMDContent.Content[i].Name.Contains("no_name"))
                {
                    Entries.Add(new LabelEntry
                    {
                        SectionID   = i,
                        LabelOffset = LabelOffset + (0x29080170 + LabelCount * 0x80)
                    });
                    LabelOffset += Encoding.ASCII.GetByteCount(GMDContent.Content[i].Name) + 1;
                }
            }

            //Header
            var Header = new Header
            {
                Magic        = GMDContent.ByteOrder == ByteOrder.BigEndian ? "\0DMG" : "GMD\0",
                Version      = 0x00010201,
                Language     = Language.ENGLISH,
                Zero1        = 0,
                LabelCount   = LabelCount,
                SectionCount = GMDContent.Content.Count(),
                LabelSize    = LabelBlob.Length,
                SectionSize  = TextBlob.Length,
                NameSize     = Encoding.ASCII.GetByteCount(GMDContent.Name)
            };

            //Write stuff
            using (var bw = new BinaryWriterX(File.Create(filename), GMDContent.ByteOrder))
            {
                //Header
                bw.WriteStruct(Header);
                bw.Write(Encoding.ASCII.GetBytes(GMDContent.Name + "\0"));

                //LabelEntries
                foreach (var entry in Entries)
                {
                    bw.WriteStruct(entry);
                }

                //Labels
                bw.Write(LabelBlob);

                //Text Sections
                bw.Write(TextBlob);
            }
        }
예제 #2
0
파일: GMDv1.cs 프로젝트: LITTOMA/Kuriimu
        public void Load(string filename)
        {
            using (var br = new BinaryReaderX(File.OpenRead(filename)))
            {
                // Set endianess
                if (br.PeekString() == "\0DMG")
                {
                    br.ByteOrder = GMDContent.ByteOrder = ByteOrder.BigEndian;
                }

                // Header
                var Header       = br.ReadStruct <Header>();
                var Name         = br.ReadCStringA();
                var HeaderLength = (int)br.BaseStream.Position;
                GMDContent.Name = Name;

                // Label Entries
                var LabelEntries    = (Header.LabelCount > 0) ? br.ReadMultiple <LabelEntry>(Header.LabelCount) : new List <LabelEntry>();
                var LabelDataOffset = (int)br.BaseStream.Position;

                // Text
                br.BaseStream.Position = 0x28 + (Header.NameSize + 1) + (Header.LabelCount * 0x8) + Header.LabelSize;
                var text = br.ReadBytes(Header.SectionSize);

                // Text deobfuscation
                var deXor = XOR.DeXOR(text);

                using (var brt = new BinaryReaderX(deXor))
                {
                    var counter = 0;
                    for (var i = 0; i < Header.SectionCount; i++)
                    {
                        var bk  = brt.BaseStream.Position;
                        var tmp = brt.ReadByte();
                        while (tmp != 0)
                        {
                            tmp = brt.ReadByte();
                        }
                        var textSize = brt.BaseStream.Position - bk;
                        brt.BaseStream.Position = bk;

                        //Get Label if existent
                        var label = "";
                        if (LabelEntries.Find(l => l.SectionID == i) != null)
                        {
                            bk = br.BaseStream.Position;
                            br.BaseStream.Position = LabelEntries.Find(l => l.SectionID == i).LabelOffset - LabelEntries.First().LabelOffset + (HeaderLength + Header.LabelCount * 0x8);
                            label = br.ReadCStringA();
                            br.BaseStream.Position = bk;
                        }

                        GMDContent.Content.Add(new Label
                        {
                            Name   = label == "" ? "no_name_" + counter++.ToString() : label,
                            Text   = brt.ReadString((int)textSize, Encoding.UTF8).Replace("\r\n", "\xa").Replace("\xa", "\r\n"),
                            TextID = i
                        });
                    }
                }
            }
        }
예제 #3
0
        public void Load(string filename)
        {
            using (var br = new BinaryReaderX(File.OpenRead(filename)))
            {
                // Set endianess
                if (br.PeekString() == "\0DMG")
                {
                    br.ByteOrder = GMDContent.ByteOrder = ByteOrder.BigEndian;
                }

                // Header
                var Header = br.ReadStruct <Header>();
                var Name   = br.ReadCStringA();
                GMDContent.Name = Name;

                //Check for platform difference
                var fullSize = 0x28 + Name.Length + 1 + Header.LabelCount * 0x14 + ((Header.LabelCount > 0) ? 0x100 * 0x4 : 0) + Header.LabelSize + Header.SectionSize;
                if (fullSize != br.BaseStream.Length)
                {
                    //Mobile structure

                    //Entry
                    var LabelEntries = (Header.LabelCount > 0) ? br.ReadMultiple <LabelEntryMobile>(Header.LabelCount) : new List <LabelEntryMobile>();

                    //Bucketlist
                    var Buckets         = (Header.LabelCount > 0) ? br.ReadMultiple <long>(0x100) : new List <long>();
                    var LabelDataOffset = (int)br.BaseStream.Position;

                    // Text
                    br.BaseStream.Position = 0x28 + (Header.NameSize + 1) + (Header.LabelCount * 0x20 + ((Header.LabelCount > 0) ? 0x100 * 0x8 : 0)) + Header.LabelSize;
                    var text = br.ReadBytes(Header.SectionSize);

                    // Text deobfuscation
                    var deXor = XOR.DeXOR(text);

                    using (var brt = new BinaryReaderX(deXor))
                    {
                        var counter = 0;
                        for (var i = 0; i < Header.SectionCount; i++)
                        {
                            var bk  = brt.BaseStream.Position;
                            var tmp = brt.ReadByte();
                            while (tmp != 0)
                            {
                                tmp = brt.ReadByte();
                            }
                            var textSize = brt.BaseStream.Position - bk;
                            brt.BaseStream.Position = bk;

                            //Get Label if existent
                            var label = "";
                            if (LabelEntries.Find(l => l.SectionID == i) != null)
                            {
                                bk = br.BaseStream.Position;
                                br.BaseStream.Position = LabelDataOffset + LabelEntries.Find(l => l.SectionID == i).LabelOffset;
                                label = br.ReadCStringA();
                                br.BaseStream.Position = bk;
                            }

                            GMDContent.Content.Add(new Label
                            {
                                Name   = label == "" ? "no_name_" + counter++.ToString("000") : label,
                                Text   = brt.ReadString((int)textSize, Encoding.UTF8).Replace("\r\n", "\xa").Replace("\xa", "\r\n"),
                                TextID = i
                            });
                        }
                    }
                }
                else
                {
                    //CTR structure

                    //Entry
                    var LabelEntries = (Header.LabelCount > 0) ? br.ReadMultiple <LabelEntry>(Header.LabelCount) : new List <LabelEntry>();

                    //Bucketlist
                    var Buckets         = (Header.LabelCount > 0) ? br.ReadMultiple <int>(0x100) : new List <int>();
                    var LabelDataOffset = (int)br.BaseStream.Position;

                    // Text
                    br.BaseStream.Position = 0x28 + (Header.NameSize + 1) + (Header.LabelCount * 0x14 + ((Header.LabelCount > 0) ? 0x100 * 0x4 : 0)) + Header.LabelSize;
                    var text = br.ReadBytes(Header.SectionSize);

                    // Text deobfuscation
                    var deXor = XOR.DeXOR(text);

                    using (var brt = new BinaryReaderX(deXor))
                    {
                        var counter = 0;
                        for (var i = 0; i < Header.SectionCount; i++)
                        {
                            var bk  = brt.BaseStream.Position;
                            var tmp = brt.ReadByte();
                            while (tmp != 0)
                            {
                                tmp = brt.ReadByte();
                            }
                            var textSize = brt.BaseStream.Position - bk;
                            brt.BaseStream.Position = bk;

                            //Get Label if existent
                            var label = "";
                            if (LabelEntries.Find(l => l.SectionID == i) != null)
                            {
                                bk = br.BaseStream.Position;
                                br.BaseStream.Position = LabelDataOffset + LabelEntries.Find(l => l.SectionID == i).LabelOffset;
                                label = br.ReadCStringA();
                                br.BaseStream.Position = bk;
                            }

                            GMDContent.Content.Add(new Label
                            {
                                Name   = label == "" ? "no_name_" + counter++.ToString("000") : label,
                                Text   = brt.ReadString((int)textSize, Encoding.UTF8).Replace("\r\n", "\xa").Replace("\xa", "\r\n"),
                                TextID = i
                            });
                        }
                    }
                }
            }
        }
예제 #4
0
        public void Save(string filename, Platform platform, Game game)
        {
            //Get Text Blob
            var TextBlob = Encoding.UTF8.GetBytes(GMDContent.Content.Aggregate("", (output, c) => output + c.Text.Replace("\r\n", "\xa").Replace("\xa", "\r\n") + "\0"));

            //ReXOR, if needed
            if (platform == Platform.CTR && game == Game.DGS2)
            {
                TextBlob = new BinaryReaderX(XOR.ReXOR(TextBlob, 1)).ReadAllBytes();
            }

            //Get Label Blob
            var LabelBlob = Encoding.ASCII.GetBytes(GMDContent.Content.Aggregate("", (output, c) => output + (c.Name.Contains("no_name") ? "" : c.Name + "\0")));

            if (platform == Platform.Mobile || platform == Platform.Switch)
            {
                //Create Entries
                var LabelEntries = new List <LabelEntryMobile>();
                var Buckets      = new Dictionary <byte, int>();
                int LabelOffset  = 0;
                var LabelCount   = GMDContent.Content.Count(c => !c.Name.Contains("no_name"));
                var counter      = 0;
                for (var i = 0; i < GMDContent.Content.Count(); i++)
                {
                    if (!GMDContent.Content[i].Name.Contains("no_name"))
                    {
                        LabelEntries.Add(new LabelEntryMobile
                        {
                            SectionID   = i,
                            Hash1       = ~Crc32.Create(GMDContent.Content[i].Name + GMDContent.Content[i].Name),
                            Hash2       = ~Crc32.Create(GMDContent.Content[i].Name + GMDContent.Content[i].Name + GMDContent.Content[i].Name),
                            LabelOffset = LabelOffset,
                            ListLink    = 0,
                            ZeroPadding = platform == Platform.Switch ? 0xCDCDCDCD : 0
                        });
                        LabelOffset += Encoding.ASCII.GetByteCount(GMDContent.Content[i].Name) + 1;

                        var bucket = (byte)(~Crc32.Create(GMDContent.Content[i].Name) & 0xff);
                        if (Buckets.ContainsKey(bucket))
                        {
                            LabelEntries[Buckets[bucket]].ListLink = counter;
                            Buckets[bucket] = counter;
                        }
                        else
                        {
                            Buckets.Add(bucket, counter);
                        }
                        counter++;
                    }
                }

                //Create bucketList Blob
                var BucketBlob = new long[0x100];
                if (LabelCount > 0)
                {
                    var counter2 = 0;
                    for (var i = 0; i < GMDContent.Content.Count(); i++)
                    {
                        if (!GMDContent.Content[i].Name.Contains("no_name"))
                        {
                            var bucket = (byte)(~Crc32.Create(GMDContent.Content[i].Name) & 0xff);
                            if (BucketBlob[bucket] == 0)
                            {
                                BucketBlob[bucket] = (counter2 == 0) ? -1 : counter2;
                            }
                            counter2++;
                        }
                    }
                }

                //Create Header
                var Header = new Header
                {
                    Magic        = "GMD\0",
                    Version      = 0x00010302,
                    Language     = Language.ENGLISH,
                    LabelCount   = LabelCount,
                    SectionCount = GMDContent.Content.Count(),
                    LabelSize    = LabelBlob.Length,
                    SectionSize  = TextBlob.Length,
                    NameSize     = Encoding.ASCII.GetByteCount(GMDContent.Name)
                };

                //Write Stuff
                using (var bw = new BinaryWriterX(File.Create(filename)))
                {
                    //Header
                    bw.WriteStruct(Header);
                    bw.Write(Encoding.ASCII.GetBytes(GMDContent.Name + "\0"));

                    //Entries
                    foreach (var entry in LabelEntries)
                    {
                        bw.WriteStruct(entry);
                    }

                    //BucketList
                    if (LabelCount > 0)
                    {
                        foreach (var bucket in BucketBlob)
                        {
                            bw.Write(bucket);
                        }
                    }

                    //Labels
                    bw.Write(LabelBlob);

                    //Text Sections
                    bw.Write(TextBlob);
                }
            }
            else if (platform == Platform.CTR)
            {
                //Create Entries
                var LabelEntries = new List <LabelEntry>();
                var Buckets      = new Dictionary <byte, int>();
                int LabelOffset  = 0;
                var LabelCount   = GMDContent.Content.Count(c => !c.Name.Contains("no_name"));
                var counter      = 0;
                for (var i = 0; i < GMDContent.Content.Count(); i++)
                {
                    if (!GMDContent.Content[i].Name.Contains("no_name"))
                    {
                        LabelEntries.Add(new LabelEntry
                        {
                            SectionID   = i,
                            Hash1       = ~Crc32.Create(GMDContent.Content[i].Name + GMDContent.Content[i].Name),
                            Hash2       = ~Crc32.Create(GMDContent.Content[i].Name + GMDContent.Content[i].Name + GMDContent.Content[i].Name),
                            LabelOffset = LabelOffset,
                            ListLink    = 0
                        });
                        LabelOffset += Encoding.ASCII.GetByteCount(GMDContent.Content[i].Name) + 1;

                        var bucket = (byte)(~Crc32.Create(GMDContent.Content[i].Name) & 0xff);
                        if (Buckets.ContainsKey(bucket))
                        {
                            LabelEntries[Buckets[bucket]].ListLink = counter;
                            Buckets[bucket] = counter;
                        }
                        else
                        {
                            Buckets.Add(bucket, counter);
                        }
                        counter++;
                    }
                }

                //Create bucketList Blob
                var BucketBlob = new int[0x100];
                if (LabelCount > 0)
                {
                    var counter2 = 0;
                    for (var i = 0; i < GMDContent.Content.Count(); i++)
                    {
                        if (!GMDContent.Content[i].Name.Contains("no_name"))
                        {
                            var bucket = (byte)(~Crc32.Create(GMDContent.Content[i].Name) & 0xff);
                            if (BucketBlob[bucket] == 0)
                            {
                                BucketBlob[bucket] = (counter2 == 0) ? -1 : counter2;
                            }
                            counter2++;
                        }
                    }
                }

                //Create Header
                var Header = new Header
                {
                    Magic        = "GMD\0",
                    Version      = 0x00010302,
                    Language     = Language.ENGLISH,
                    LabelCount   = LabelCount,
                    SectionCount = GMDContent.Content.Count(),
                    LabelSize    = LabelBlob.Length,
                    SectionSize  = TextBlob.Length,
                    NameSize     = Encoding.ASCII.GetByteCount(GMDContent.Name)
                };

                //Write Stuff
                using (var bw = new BinaryWriterX(File.Create(filename)))
                {
                    //Header
                    bw.WriteStruct(Header);
                    bw.Write(Encoding.ASCII.GetBytes(GMDContent.Name + "\0"));

                    //Entries
                    foreach (var entry in LabelEntries)
                    {
                        bw.WriteStruct(entry);
                    }

                    //BucketList
                    if (LabelCount > 0)
                    {
                        foreach (var bucket in BucketBlob)
                        {
                            bw.Write(bucket);
                        }
                    }

                    //Labels
                    bw.Write(LabelBlob);

                    //Text Sections
                    bw.Write(TextBlob);
                }
            }
        }
예제 #5
0
파일: GMDv1.cs 프로젝트: wabberz/Kuriimu
        public void Save(string filename, Platform platform, Game game)
        {
            //Get Text Section
            var TextBlob = Encoding.UTF8.GetBytes(GMDContent.Content.Aggregate("", (output, c) => output + c.Text.Replace("\r\n", "\xa").Replace("\xa", "\r\n") + "\0"));

            //XOR, if needed
            if (platform == Platform.CTR && game == Game.DD)
            {
                TextBlob = new BinaryReaderX(XOR.ReXOR(TextBlob, 0)).ReadAllBytes();
            }

            //Get Label Blob
            var LabelBlob = Encoding.ASCII.GetBytes(GMDContent.Content.Aggregate("", (output, c) => output + (c.Name.Contains("no_name_") ? "" : c.Name + "\0")));

            //Create LabelEntries
            var LabelEntries = new List <LabelEntry>();
            var LabelOffset  = 0;
            var LabelCount   = GMDContent.Content.Count(c => !c.Name.Contains("no_name_"));

            for (var i = 0; i < GMDContent.Content.Count(); i++)
            {
                if (GMDContent.Content[i].Name.Contains("no_name_"))
                {
                    continue;
                }

                LabelEntries.Add(new LabelEntry
                {
                    SectionID   = i,
                    LabelOffset = LabelOffset + _firstLabelOffset
                });
                LabelOffset += Encoding.ASCII.GetByteCount(GMDContent.Content[i].Name) + 1;
            }

            //Header
            FileHeader.LabelCount   = LabelCount;
            FileHeader.SectionCount = GMDContent.Content.Count;
            FileHeader.LabelSize    = LabelBlob.Length;
            FileHeader.SectionSize  = TextBlob.Length;
            FileHeader.NameSize     = Encoding.ASCII.GetByteCount(GMDContent.Name);

            //Write stuff
            using (var bw = new BinaryWriterX(File.Create(filename), GMDContent.ByteOrder))
            {
                //Header
                bw.WriteStruct(FileHeader);
                bw.Write(Encoding.ASCII.GetBytes(GMDContent.Name + "\0"));

                //LabelEntries
                foreach (var entry in LabelEntries)
                {
                    bw.WriteStruct(entry);
                }

                //Labels
                bw.Write(LabelBlob);

                //Text Sections
                bw.Write(TextBlob);
            }
        }
예제 #6
0
파일: GMD.cs 프로젝트: mhdasding/Kuriimu
        public GMD(Stream input)
        {
            using (var br = new BinaryReaderX(input))
            {
                // Set endianess
                if (br.PeekString() == "\0DMG")
                {
                    br.ByteOrder = ByteOrder = ByteOrder.BigEndian;
                }

                // Header
                Header = br.ReadStruct <Header>();
                Name   = br.ReadCStringA();

                // Entries
                if (Header.Version == Versions.Version1)
                {
                    EntriesV1 = br.ReadMultiple <EntryV1>((int)Header.LabelCount);
                }
                else if (Header.Version == Versions.Version2)
                {
                    EntriesV2 = br.ReadMultiple <EntryV2>((int)Header.LabelCount);
                }

                // Unknown Version 2 Section
                if (Header.Version == Versions.Version2)
                {
                    var bk   = br.BaseStream.Position;
                    var temp = br.ReadUInt32();
                    while (temp < 0x100000 || temp == 0xffffffff)
                    {
                        temp = br.ReadUInt32();
                    }
                    br.BaseStream.Position -= 4;

                    temp = br.ReadByte();
                    while (temp == 0)
                    {
                        temp = br.ReadByte();
                    }
                    br.BaseStream.Position--;

                    var unkSize = br.BaseStream.Position - bk;
                    br.BaseStream.Position = bk;

                    UnknownV2 = br.ReadBytes((int)unkSize);
                }

                // Labels
                var counter = 0;
                for (var i = 0; i < Header.LabelCount; i++)
                {
                    if (Header.LabelSize > 0)
                    {
                        Names.Add(br.ReadCStringA());
                    }
                    else
                    {
                        Names.Add("no_name_" + i.ToString("0000"));
                    }

                    counter = i;
                }

                // Text
                var text = br.ReadBytes((int)Header.SectionSize);

                // Text deobfuscation
                var xor = new XOR(Header.Version);
                IsXORed = XOR.IsXORed(new MemoryStream(text));
                if (IsXORed)
                {
                    text = xor.Deobfuscate(text);
                }

                using (var brt = new BinaryReaderX(new MemoryStream(text), ByteOrder))
                {
                    for (var i = 0; i < Header.SectionCount; i++)
                    {
                        var bk  = brt.BaseStream.Position;
                        var tmp = brt.ReadByte();
                        while (tmp != 0)
                        {
                            tmp = brt.ReadByte();
                        }
                        var textSize = brt.BaseStream.Position - bk;
                        brt.BaseStream.Position = bk;

                        Labels.Add(new Label
                        {
                            Name   = i < Header.LabelCount ? Names[i] : "no_name_" + counter.ToString("0000"),
                            Text   = brt.ReadString((int)textSize, Encoding.UTF8),
                            TextID = i
                        });

                        if (i >= Header.LabelCount)
                        {
                            counter++;
                        }
                    }
                }
            }
        }
예제 #7
0
파일: GMD.cs 프로젝트: mhdasding/Kuriimu
        public void Save(Stream output)
        {
            using (var bw = new BinaryWriterX(output, ByteOrder))
            {
                bw.BaseStream.Position = HeaderLength + Header.NameSize + 1;

                // Section Entries
                if (Header.Version == Versions.Version1)
                {
                    foreach (var entry in EntriesV1)
                    {
                        bw.WriteStruct(entry);
                    }
                }
                else if (Header.Version == Versions.Version2)
                {
                    foreach (var entry in EntriesV2)
                    {
                        bw.WriteStruct(entry);
                    }
                }

                // Unknown Version 2 Section
                if (Header.Version == Versions.Version2)
                {
                    bw.Write(UnknownV2);
                }

                // Labels
                uint labelSize = 0;
                for (var i = 0; i < Header.LabelCount; i++)
                {
                    bw.WriteASCII(Names[i]);
                    bw.Write((byte)0);
                    labelSize += (uint)Names[i].Length + 1;
                }
                Header.LabelSize = labelSize;

                // Sections
                var textStart = bw.BaseStream.Position;

                var textS = new MemoryStream();
                using (var textW = new BinaryWriterX(textS, true))
                {
                    foreach (var label in Labels)
                    {
                        textW.Write(Encoding.UTF8.GetBytes(label.Text));
                        textW.Write((byte)0);
                    }
                }
                //ReXOR if needed, only for version 1 for now
                if (Header.Version == Versions.Version1 && IsXORed)
                {
                    var xor = new XOR(Header.Version);
                    var tmp = xor.Obfuscate(new BinaryReaderX(textS).ReadAllBytes());
                    textS.Position = 0;
                    new BinaryWriterX(textS, true).Write(tmp);
                }
                bw.Write(new BinaryReaderX(textS).ReadAllBytes());

                Header.SectionSize = (uint)(bw.BaseStream.Position - textStart);

                // Header
                bw.BaseStream.Position = 0;
                bw.WriteStruct(Header);
                bw.WriteASCII(Name);
                bw.Write((byte)0);
            }
        }