Ejemplo n.º 1
0
        private static string MaybeExpandAutoTranslatorMessage(string Text)
        {
            // Reference to a string table entry? => return referenced string
            if (Text != null && Text.Length > 2 && Text.Length <= 6 && Text[0] == '@')
            {
                char ReferenceType = Text[1];
                try
                {
                    ushort ID = ushort.Parse(Text.Substring(2), NumberStyles.AllowHexSpecifier);
                    switch (ReferenceType)
                    {
                    case 'A':
                        return(FFXIResourceManager.GetAreaName(ID));

                    case 'C':
                        return(FFXIResourceManager.GetSpellName(ID));

                    case 'J':
                        return(FFXIResourceManager.GetJobName(ID));

                    case 'Y':
                        return(FFXIResourceManager.GetAbilityName(ID));
                    }
                }
                catch {}
            }
            return(Text);
        }
Ejemplo n.º 2
0
        private static string GetResourceStringInternal(uint ResourceID)
        {
            byte   Category = (byte)((ResourceID >> 24) & 0xff);
            byte   Language = (byte)((ResourceID >> 16) & 0xff);
            ushort ID       = (ushort)(ResourceID & 0xffff);

            switch (Category)
            {
            case 0x02:
                return(FFXIResourceManager.GetAutoTranslatorMessage(Category, Language, ID));

            case 0x04:
                return(FFXIResourceManager.GetAutoTranslatorMessage(Category, Language, ID));

            case 0x06:
                return(FFXIResourceManager.GetItemName(Language, ID));

            case 0x07:
                return(FFXIResourceManager.GetItemName(Language, ID));

            case 0x08:
                return(FFXIResourceManager.GetItemName(Language, ID));

            case 0x09:
                return(FFXIResourceManager.GetItemName(Language, ID));

            case 0x13:
                return(FFXIResourceManager.GetKeyItemName(Language, ID));
            }
            return(null);
        }
Ejemplo n.º 3
0
 public static string GetItemName(byte Language, ushort ID)
 {
     foreach (ushort ItemDAT in FFXIResourceManager.ItemDATs)
     {
         BinaryReader BR = FFXIResourceManager.OpenDATFile(ItemDAT);
         if (BR != null)
         {
             Item.Type T;
             Item.DeduceType(BR, out T);
             long Offset = (ID & 0xfff) * 0xc00;
             if (BR.BaseStream.Length >= Offset + 0xc00)
             {
                 Item I = new Item();
                 BR.BaseStream.Position = Offset;
                 if (I.Read(BR, T) && (uint)I.GetFieldValue("id") == ID)
                 {
                     BR.Close();
                     return(I.GetFieldText("name"));
                 }
             }
             BR.Close();
         }
     }
     return(null);
 }
Ejemplo n.º 4
0
        public static string GetAutoTranslatorMessage(byte Category, byte Language, ushort ID)
        {
            // FIXME: This is probably a stale file
            BinaryReader BR = FFXIResourceManager.OpenDATFile(55665); // JP = 55545

            if (BR != null)
            {
                while (BR.BaseStream.Position + 76 <= BR.BaseStream.Length)
                {
                    byte   GroupCat  = BR.ReadByte();
                    byte   GroupLang = BR.ReadByte();
                    ushort GroupID   = (ushort)(BR.ReadByte() * 256 + BR.ReadByte());
                    BR.BaseStream.Position += 64;
                    uint Messages  = BR.ReadUInt32();
                    uint DataBytes = BR.ReadUInt32();
                    if (GroupID == (ID & 0xff00))
                    {
                        // We found the right group (ignoring category & language for now)
                        for (uint i = 0; i < Messages && BR.BaseStream.Position + 5 < BR.BaseStream.Length; ++i)
                        {
                            byte   MessageCat  = BR.ReadByte();
                            byte   MessageLang = BR.ReadByte();
                            ushort MessageID   = (ushort)(BR.ReadByte() * 256 + BR.ReadByte());
                            byte   TextLength  = BR.ReadByte();
                            if (MessageID == ID)
                            {
                                // We found the right message (ignoring category & language for now)
                                byte[] MessageBytes = BR.ReadBytes(TextLength);
                                BR.Close();
                                string MessageText = FFXIResourceManager.E.GetString(MessageBytes).TrimEnd('\0');
                                return(FFXIResourceManager.MaybeExpandAutoTranslatorMessage(MessageText));
                            }
                            else
                            {
                                BR.BaseStream.Position += TextLength;
                                if (MessageLang == 0x04)
                                {
                                    // There is an extra string to skip for Japanese entries
                                    TextLength              = BR.ReadByte();
                                    BR.BaseStream.Position += TextLength;
                                }
                            }
                        }
                    }
                    else
                    {
                        BR.BaseStream.Position += DataBytes;
                    }
                }
                BR.Close();
            }
            return(null);
        }
Ejemplo n.º 5
0
        public static string GetKeyItemName(byte Language, ushort ID)
        {
#if false                                                          // FIXME: Not updated to new DAT file format
            BinaryReader BR = FFXIResourceManager.OpenDATFile(82); // JP = 80
            if (BR != null)
            {
                if (Encoding.ASCII.GetString(BR.ReadBytes(4)) == "menu" && BR.ReadUInt32() == 0x101)
                {
                    BR.BaseStream.Position = 0x20;
                    while (BR.BaseStream.Position < BR.BaseStream.Length)
                    {
                        long   Offset    = BR.BaseStream.Position;
                        string ShortName = Encoding.ASCII.GetString(BR.ReadBytes(4));
                        uint   SizeInfo  = BR.ReadUInt32();
                        if (BR.ReadUInt64() != 0)
                        {
                            break;
                        }
                        if (ShortName == "sc_i")
                        {
                            BR.BaseStream.Position += 0x14;
                            uint EntryCount = BR.ReadUInt32();
                            for (uint i = 0; i < EntryCount; ++i)
                            {
                                if (BR.ReadUInt32() == ID)
                                {
                                    BR.BaseStream.Position += 4;
                                    BR.BaseStream.Position  = Offset + 0x10 + BR.ReadUInt32();
                                    return(FFXIEncryption.ReadEncodedString(BR, FFXIResourceManager.E));
                                }
                                BR.BaseStream.Position += 16;
                            }
                        }
                        // Skip to next one
                        BR.BaseStream.Position = Offset + ((SizeInfo & 0xFFFFFF80) >> 3);
                    }
                }
                BR.Close();
            }
            return(null);
#else
            return(String.Format("Key Item #{0}", ID));
#endif
        }
Ejemplo n.º 6
0
        private static string GetStringTableEntry(ushort FileNumber, ushort ID)
        {
            BinaryReader BR = FFXIResourceManager.OpenDATFile(FileNumber);

            try
            {
                if (BR != null)
                {
                    BR.BaseStream.Position = 0x18;
                    // FIXME: Assumes single-string table; code should be made more generic.
                    uint HeaderBytes = BR.ReadUInt32();
                    uint EntryBytes  = BR.ReadUInt32();
                    BR.ReadUInt32();
                    uint DataBytes = BR.ReadUInt32();
                    if (HeaderBytes == 0x40 && ID * 8 < EntryBytes && HeaderBytes + EntryBytes + DataBytes == BR.BaseStream.Length)
                    {
                        BR.BaseStream.Position = 0x40 + ID * 8;
                        uint Offset = (BR.ReadUInt32() ^ 0xFFFFFFFF);
                        uint Length = (BR.ReadUInt32() ^ 0xFFFFFFFF) - 40;
                        if (Length >= 0 && 40 + Offset + Length <= DataBytes)
                        {
                            BR.BaseStream.Position = HeaderBytes + EntryBytes + 40 + Offset;
                            byte[] TextBytes = BR.ReadBytes((int)Length);
                            for (uint i = 0; i < TextBytes.Length; ++i)
                            {
                                TextBytes[i] ^= 0xff;
                            }
                            return(E.GetString(TextBytes).TrimEnd('\0'));
                        }
                    }
                }
            }
            catch
            {
                // ignore
            }
            finally
            {
                BR.Close();
            }
            return(null);
        }
Ejemplo n.º 7
0
            private string MaybeExpand(ref string Text)
            {
                // Reference to a string table entry? => return referenced string
                if (Text != null && Text.Length > 2 && Text.Length <= 6 && Text[0] == '@')
                {
                    char ReferenceType = Text[1];
                    try {
                        ushort EntryNumber = ushort.Parse(Text.Substring(2), NumberStyles.AllowHexSpecifier);
                        switch (ReferenceType)
                        {
                        case 'A': Text = FFXIResourceManager.GetAreaName(EntryNumber); break;

                        case 'C': Text = FFXIResourceManager.GetSpellName(EntryNumber); break;

                        case 'J': Text = FFXIResourceManager.GetJobName(EntryNumber); break;

                        case 'Y': Text = FFXIResourceManager.GetAbilityName(EntryNumber); break;
                        }
                    } catch { }
                }
                return(Text);
            }
Ejemplo n.º 8
0
        public static string GetSpellName(ushort ID)
        {
#if false // FIXME: Not updated to new DAT file format
            BinaryReader BR = FFXIResourceManager.OpenDATFile(86);
            if (BR != null)
            {
                if ((ID + 1) * 0x400 <= BR.BaseStream.Length)
                {
                    BR.BaseStream.Position = ID * 0x400;
                    byte[] SpellData = BR.ReadBytes(0x400);
                    BR.Close();
                    if (FFXIEncryption.DecodeDataBlock(SpellData))
                    {
                        return(FFXIResourceManager.E.GetString(SpellData, 0x3d, 20).TrimEnd('\0'));
                    }
                }
                BR.Close();
            }
            return(null);
#else
            return(String.Format("Spell #{0}", ID));
#endif
        }
Ejemplo n.º 9
0
        public override string GetString(byte[] bytes, int index, int count)
        {
            string DecodedString = String.Empty;

            for (int pos = index; pos < index + count; ++pos)
            {
                // FFXI Extension: Elemental symbols
                if (bytes[pos] == 0xEF && (pos + 1) < (index + count) && bytes[pos + 1] >= 0x1F && bytes[pos + 1] <= 0x26)
                {
                    DecodedString += String.Format("{0}Element: {1}{2}", FFXIEncoding.SpecialMarkerStart, (Element)(bytes[++pos] - 0x1f), FFXIEncoding.SpecialMarkerEnd);
                    continue;
                }
                // FFXI Extension: Open/Close AutoTranslator Text
                if (bytes[pos] == 0xEF && (pos + 1) < (index + count) && bytes[pos + 1] >= 0x27 && bytes[pos + 1] <= 0x28)
                {
                    DecodedString += FFXIEncoding.SpecialMarkerStart;
                    DecodedString += "AutoTrans: ";
                    switch (bytes[++pos])
                    {
                    case 0x27: DecodedString += "Start"; break;

                    case 0x28: DecodedString += "End";  break;
                    }
                    DecodedString += FFXIEncoding.SpecialMarkerEnd;
                    continue;
                }
                // FFXI Extension: Resource Text (Auto-Translator/Item/Key Item)
                if (bytes[pos] == 0xFD && pos + 5 < index + count && bytes[pos + 5] == 0xFD)
                {
                    uint ResourceID = 0;
                    ResourceID   <<= 8; ResourceID += bytes[pos + 1];
                    ResourceID   <<= 8; ResourceID += bytes[pos + 2];
                    ResourceID   <<= 8; ResourceID += bytes[pos + 3];
                    ResourceID   <<= 8; ResourceID += bytes[pos + 4];
                    DecodedString += String.Format("{0}[{1:X8}] {2}{3}", FFXIEncoding.SpecialMarkerStart, ResourceID, FFXIResourceManager.GetResourceString(ResourceID), FFXIEncoding.SpecialMarkerEnd);
                    pos           += 5;
                    continue;
                }
                // Default behaviour - use table
                ushort DecodedChar = this.GetTableEntry(0, bytes[pos]);
                if (DecodedChar == 0xFFFE) // Possible Lead Byte
                {
                    if (pos + 1 < index + count)
                    {
                        byte Table = bytes[pos++];
                        DecodedChar = this.GetTableEntry(Table, bytes[pos]);
                        if (DecodedChar == 0xFFFF)
                        {
                            DecodedString += String.Format("{0}BAD CHAR: {1:X2}{2:X2}{3}", FFXIEncoding.SpecialMarkerStart, Table, bytes[pos], FFXIEncoding.SpecialMarkerEnd);
                        }
                        else
                        {
                            DecodedString += (char)DecodedChar;
                        }
                    }
                    else
                    {
                        DecodedString += String.Format("{0}BAD CHAR: {1:X2}{2}", FFXIEncoding.SpecialMarkerStart, bytes[pos], FFXIEncoding.SpecialMarkerEnd);
                    }
                }
                else if (DecodedChar == 0xFFFF)
                {
                    DecodedString += String.Format("{0}BAD CHAR: {1:X2}{2}", FFXIEncoding.SpecialMarkerStart, bytes[pos], FFXIEncoding.SpecialMarkerEnd);
                }
                else
                {
                    DecodedString += (char)DecodedChar;
                }
            }
            return(DecodedString);
        }
Ejemplo n.º 10
0
 public static string GetRegionName(ushort ID)
 {
     return(FFXIResourceManager.GetStringTableEntry(55654, ID));
 }
Ejemplo n.º 11
0
 public static string GetJobName(ushort ID)
 {
     return(FFXIResourceManager.GetStringTableEntry(55467, ID));
 }
Ejemplo n.º 12
0
 public static bool IsValidResourceID(uint ResourceID)
 {
     return(FFXIResourceManager.GetResourceStringInternal(ResourceID) != null);
 }
Ejemplo n.º 13
0
        public static string GetResourceString(uint ResourceID)
        {
            string ResourceString = FFXIResourceManager.GetResourceStringInternal(ResourceID);

            return((ResourceString == null) ? I18N.GetText("BadResID") : ResourceString);
        }