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); }
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); }
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); }
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); }
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 }
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); }
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); }
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 }
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); }
public static string GetRegionName(ushort ID) { return(FFXIResourceManager.GetStringTableEntry(55654, ID)); }
public static string GetJobName(ushort ID) { return(FFXIResourceManager.GetStringTableEntry(55467, ID)); }
public static bool IsValidResourceID(uint ResourceID) { return(FFXIResourceManager.GetResourceStringInternal(ResourceID) != null); }
public static string GetResourceString(uint ResourceID) { string ResourceString = FFXIResourceManager.GetResourceStringInternal(ResourceID); return((ResourceString == null) ? I18N.GetText("BadResID") : ResourceString); }