예제 #1
0
        private static string GetReader(BdatMember member)
        {
            string name      = GetIdentifier(member.Name);
            string memberPos = member.MemberPos > 0 ? $" + {member.MemberPos}" : string.Empty;

            switch (member.ValType)
            {
            case BdatValueType.UInt8:
                return($"item.{name} = file[itemOffset{memberPos}];");

            case BdatValueType.UInt16:
                return($"item.{name} = BitConverter.ToUInt16(file, itemOffset{memberPos});");

            case BdatValueType.UInt32:
                return($"item.{name} = BitConverter.ToUInt32(file, itemOffset{memberPos});");

            case BdatValueType.Int8:
                return($"item.{name} = (sbyte)file[itemOffset{memberPos}];");

            case BdatValueType.Int16:
                return($"item.{name} = BitConverter.ToInt16(file, itemOffset{memberPos});");

            case BdatValueType.Int32:
                return($"item.{name} = BitConverter.ToInt32(file, itemOffset{memberPos});");

            case BdatValueType.String:
                return($"item.{name} = Stuff.GetUTF8Z(file, tableOffset + BitConverter.ToInt32(file, itemOffset{memberPos}));");

            case BdatValueType.FP32:
                return($"item.{name} = BitConverter.ToSingle(file, itemOffset{memberPos});");
            }
            throw new ArgumentOutOfRangeException();
        }
예제 #2
0
        private static BdatStringItem ReadItem(BdatTable table, int itemIndex)
        {
            int itemOffset = table.ItemTableOffset + itemIndex * table.ItemSize;

            var item = new BdatStringItem();

            foreach (BdatMember member in table.Members)
            {
                switch (member.Type)
                {
                case BdatMemberType.Scalar:
                    string v = ReadValue(table.Data, itemOffset + member.MemberPos, member.ValType);
                    item.AddMember(member.Name, new BdatStringValue(v, item, member));
                    break;

                case BdatMemberType.Array:
                    string[] a = ReadArray(table.Data, itemOffset + member.MemberPos, member);
                    item.AddMember(member.Name, new BdatStringValue(a, item, member));
                    break;

                case BdatMemberType.Flag:
                    BdatMember flagsMember = table.Members[member.FlagVarIndex];
                    string     f           = ReadFlag(table.Data, itemOffset, member, flagsMember);
                    item.AddMember(member.Name, new BdatStringValue(f, item, member));
                    break;
                }
            }

            return(item);
        }
예제 #3
0
        private static string[] ReadArray(DataBuffer table, int arrayOffset, BdatMember member)
        {
            var values   = new string[member.ArrayCount];
            int typeSize = GetTypeSize(member.ValType);

            for (int i = 0, offset = arrayOffset; i < member.ArrayCount; i++, offset += typeSize)
            {
                values[i] = ReadValue(table, offset, member.ValType);
            }

            return(values);
        }
예제 #4
0
파일: Metadata.cs 프로젝트: koken3d4/XbTool
        public static void SetXb2EffectCaptions(BdatStringCollection tables)
        {
            if (!tables.Tables.ContainsKey("BTL_Enhance") || !tables.Tables.ContainsKey("BTL_EnhanceEff"))
            {
                return;
            }

            BdatStringTable enhances = tables["BTL_Enhance"];
            BdatStringTable effects  = tables["BTL_EnhanceEff"];

            List <BdatMember> newMembers = effects.Members.ToList();
            var captionMember            = new BdatMember("Caption", BdatMemberType.Scalar, BdatValueType.String);

            newMembers.Add(captionMember);
            effects.Members = newMembers.ToArray();

            foreach (BdatStringItem effect in effects.Items)
            {
                effect.AddMember("Caption", new BdatStringValue("0", effect, captionMember));
                effect["Caption"].Display = "";
            }

            foreach (BdatStringItem enhance in enhances.Items)
            {
                int captionId = int.Parse(enhance["Caption"].ValueString);
                if (captionId == 0)
                {
                    continue;
                }

                BdatStringValue effect = effects[int.Parse(enhance["EnhanceEffect"].ValueString)]["Caption"];

                string caption = tables["btl_enhance_cap"][captionId]?["name"].ValueString;

                effect.Value   = captionId.ToString();
                effect.Display = caption;
            }

            foreach (BdatStringItem enhance in enhances.Items)
            {
                int effectCaptionId  = int.Parse(enhance["EnhanceEffect"].ValueString);
                int enhanceCaptionId = int.Parse(enhance["Caption"].ValueString);
                if (enhanceCaptionId != 0 || effectCaptionId == 0)
                {
                    continue;
                }

                BdatStringValue effect = effects[effectCaptionId]["Caption"];
                enhance["Caption"].Value = effect.ValueString;
            }
        }
예제 #5
0
        private static void GetArrayReader(BdatMember member, Indenter sb)
        {
            string name      = GetIdentifier(member.Name);
            int    itemSize  = GetSize(member.ValType);
            string memberPos = member.MemberPos > 0 ? $" + {member.MemberPos}" : string.Empty;

            sb.AppendLine($"for (int i = 0, offset = itemOffset{memberPos}; i < {member.ArrayCount}; i++, offset += {itemSize})");
            sb.AppendLineAndIncrease("{");

            switch (member.ValType)
            {
            case BdatValueType.UInt8:
                sb.AppendLine($"item.{name}[i] = file[offset];");
                break;

            case BdatValueType.UInt16:
                sb.AppendLine($"item.{name}[i] = BitConverter.ToUInt16(file, offset);");
                break;

            case BdatValueType.UInt32:
                sb.AppendLine($"item.{name}[i] = BitConverter.ToUInt32(file, offset);");
                break;

            case BdatValueType.Int8:
                sb.AppendLine($"item.{name}[i] = (sbyte)file[offset];");
                break;

            case BdatValueType.Int16:
                sb.AppendLine($"item.{name}[i] = BitConverter.ToInt16(file, offset);");
                break;

            case BdatValueType.Int32:
                sb.AppendLine($"item.{name}[i] = BitConverter.ToInt32(file, offset);");
                break;

            case BdatValueType.String:
                sb.AppendLine($"item.{name}[i] = Stuff.GetUTF8Z(file, tableOffset + BitConverter.ToInt32(file, offset));");
                break;

            case BdatValueType.FP32:
                sb.AppendLine($"item.{name}[i] = BitConverter.ToSingle(file, offset);");
                break;
            }

            sb.DecreaseAndAppendLine("}");
        }
예제 #6
0
        private static string ReadFlag(DataBuffer table, int itemOffset, BdatMember member, BdatMember flagsMember)
        {
            uint flags = uint.Parse(ReadValue(table, itemOffset + flagsMember.MemberPos, flagsMember.ValType));

            return(((flags & member.FlagMask) != 0).ToString());
        }
예제 #7
0
파일: Metadata.cs 프로젝트: koken3d4/XbTool
        public static void ResolveItemRef(BdatStringValue value)
        {
            if (value.Resolved)
            {
                return;
            }

            BdatStringItem       item   = value.Parent;
            BdatStringTable      table  = item.Table;
            BdatStringCollection tables = table.Collection;
            BdatMember           member = value.Member;
            BdatFieldInfo        field  = member.Metadata;

            if (value.Array != null)
            {
                foreach (BdatStringValue element in value.Array)
                {
                    ResolveItemRef(element);
                }

                value.Resolved = true;
                return;
            }

            if (field == null)
            {
                value.Resolved = true;
                return;
            }

            if (!int.TryParse(value.ValueString, out int refId))
            {
                value.Resolved = true;
                return;
            }

            refId += field.Adjust;

            switch (field.Type)
            {
            case BdatFieldType.Message:
                value.Display = tables[field.RefTable][refId]?["name"].DisplayString;
                if (string.IsNullOrWhiteSpace(value.DisplayString) && refId > 0)
                {
                    value.Display = refId.ToString();
                }
                break;

            case BdatFieldType.Reference:
                ApplyRef(field.RefTable);
                break;

            case BdatFieldType.OneWayReference:
                ApplyRef(field.RefTable, false);
                break;

            case BdatFieldType.Item:
                if (tables.Game == Game.XB2)
                {
                    ApplyRef(BdatStringTools.GetItemTableXb2(refId));
                }
                if (tables.Game == Game.XB1 || tables.Game == Game.XB1DE)
                {
                    var itemType = (ItemTypeXb1)int.Parse(item[field.RefField].ValueString);
                    ApplyRef(BdatStringTools.GetItemTableXb1(itemType));
                }
                if (tables.Game == Game.XBX)
                {
                    var itemType = (ItemTypeXbx)int.Parse(item[field.RefField].ValueString);
                    ApplyRef(BdatStringTools.GetItemTableXbx(itemType));
                }

                break;

            case BdatFieldType.Event:
                ApplyRef(BdatStringTools.GetEventTable(refId));
                break;

            case BdatFieldType.EventSetup:
                ApplyRef(BdatStringTools.GetEventSetupTable(refId));
                break;

            case BdatFieldType.Quest when tables.Game == Game.XB1DE:
                ApplyRef(BdatStringTools.GetQuestJournalTableXb1(refId));
                break;

            case BdatFieldType.QuestMenu when tables.Game == Game.XB1DE:
                ApplyRef(BdatStringTools.GetQuestMenuTableXb1(refId));
                break;

            case BdatFieldType.Quest:
                throw new InvalidDataException();

            case BdatFieldType.QuestFlag:
                ApplyRef(BdatStringTools.GetQuestListTable(refId));
                break;

            case BdatFieldType.QuestFlagIra:
                ApplyRef(BdatStringTools.GetQuestListIraTable(refId));
                break;

            case BdatFieldType.Condition:
                if (tables.Game == Game.XB2)
                {
                    var conditionType = (ConditionType)int.Parse(item[field.RefField].ValueString);
                    ApplyRef(BdatStringTools.GetConditionTable(conditionType));
                }
                if (tables.Game == Game.XBX)
                {
                    var conditionType = (ConditionTypeXbx)int.Parse(item[field.RefField].ValueString);
                    ApplyRef(BdatStringTools.GetConditionTableXbx(conditionType));
                }

                break;

            case BdatFieldType.Task when tables.Game == Game.XB2:
                var taskType = (TaskType)int.Parse(item[field.RefField].ValueString);
                ApplyRef(BdatStringTools.GetTaskTable(taskType));
                break;

            case BdatFieldType.Task when tables.Game == Game.XB1 || tables.Game == Game.XB1DE:
                var taskTypeXb1 = (TaskTypeXb1)int.Parse(item[field.RefField].ValueString);
                int itemId      = int.Parse(item[field.Field].ValueString);
                ApplyRef(BdatStringTools.GetTaskTableXb1(taskTypeXb1, itemId));
                break;

            case BdatFieldType.ShopTable:
                var shopType = (ShopType)int.Parse(item[field.RefField].ValueString);
                ApplyRef(BdatStringTools.GetShopTable(shopType));
                break;

            case BdatFieldType.Character:
                ApplyRef(BdatStringTools.GetCharacterTable(refId));
                break;

            case BdatFieldType.Enhance:
                if (tables.Game == Game.XB2)
                {
                    value.Display = BdatStringTools.GetEnhanceCaption(value);
                }
                if (tables.Game == Game.XBX)
                {
                    value.Display = BdatStringTools.GetEnhanceCaptionXbx(value);
                }
                break;

            case BdatFieldType.WeatherIdMap:
                value.Display = BdatStringTools.PrintWeatherIdMap(refId, 13, tables);
                break;

            case BdatFieldType.PouchBuff:
                value.Display = GetPouchBuffCaption(value);
                break;

            case BdatFieldType.Flag:
                AddFlag(tables, field.RefTable, refId, value);
                break;

            case BdatFieldType.GameFlag:
                string flagType = item[field.RefField].ValueString;
                AddFlag(tables, flagType + "bit", refId, value);
                break;

            case BdatFieldType.Change:
                var changeType = (ChangeType)int.Parse(item[field.RefField].ValueString);
                if (changeType == ChangeType.scenario)
                {
                    AddFlag(tables, "Scenario", refId, value);
                }
                break;

            case BdatFieldType.ItemComment:
                ApplyRef(item.Id >= 1852 ? "MNU_item_mes_b" : "MNU_item_mes_a");
                break;

            case BdatFieldType.Layer:
                ApplyRef(BdatStringTools.GetLayerTable(refId));
                break;

            case BdatFieldType.Place:
                var    placeCat   = (PlaceCategory)int.Parse(item[field.RefField].ValueString);
                string placeTable = GimmickData.GetPlaceTable(placeCat, refId);
                if (placeTable != null)
                {
                    ApplyRef(placeTable);
                }
                break;

            case BdatFieldType.Enemy when tables.Game == Game.XB1DE:
                ApplyRef(BdatStringTools.GetEnemyTableXb1(refId), member.Type != BdatMemberType.None);
                break;

            case BdatFieldType.ArmorStyle when tables.Game == Game.XB1DE:
            {
                int characterId = int.Parse(item[field.RefField].ValueString);
                int equipItemId = int.Parse(item[field.Field].ValueString);

                if (equipItemId != 0)
                {
                    ApplyRef(BdatStringTools.GetArmorStyleTableXb1(characterId));
                }
                break;
            }

            case BdatFieldType.WeaponStyle when tables.Game == Game.XB1DE:
            {
                int characterId = 0;
                int equipItemId = int.Parse(item[field.Field].ValueString);

                for (int i = 0; i <= 16; i++)
                {
                    string fieldName = $"equip_pc{i}";
                    if (item.Values.TryGetValue(fieldName, out BdatStringValue equipPcValue))
                    {
                        if (equipPcValue.ValueString == "1")
                        {
                            characterId = i;
                            break;
                        }
                    }
                }

                if (equipItemId != 0 && characterId != 0)
                {
                    ApplyRef(BdatStringTools.GetWeaponStyleTableXb1(characterId));
                }
                break;
            }
            }

            if (field.EnumType != null)
            {
                if (field.EnumType.GetCustomAttributes(typeof(FlagsAttribute), false).Length > 0)
                {
                    value.Display = BdatStringTools.PrintEnumFlags(field.EnumType, refId);
                }
                else
                {
                    value.Display = Enum.GetName(field.EnumType, refId);
                }
            }

            value.Resolved = true;

            void ApplyRef(string refTable, bool addReverseRef = true)
            {
                if (refTable == null || !tables.Tables.ContainsKey(refTable) || !tables[refTable].ContainsId(refId))
                {
                    value.Display = refId == 0 ? null : refId.ToString();
                    return;
                }

                BdatStringValue reft = tables[refTable][refId].Display;

                if (reft != null)
                {
                    if (!reft.Resolved)
                    {
                        ResolveItemRef(reft);
                    }

                    if (!string.IsNullOrWhiteSpace(reft.DisplayString))
                    {
                        value.Display = reft.Display;
                    }
                }

                value.Reference = tables[refTable][refId];

                if (addReverseRef)
                {
                    tables[refTable][refId].ReferencedBy.Add(value.Parent);
                }
            }
        }
예제 #8
0
        public static void PrintTable(BdatStringTable table, Indenter sb)
        {
            sb.AppendLineAndIncrease("<table class=\"sortable\">");
            sb.AppendLineAndIncrease("<thead>");
            sb.AppendLineAndIncrease("<tr id=\"header\">");
            sb.AppendLine("<th class=\" dir-d \">ID</th>");
            sb.AppendLine("<th>Referenced By</th>");

            foreach (BdatMember member in table.Members)
            {
                if (member.Metadata?.Type == BdatFieldType.Hide)
                {
                    continue;
                }

                bool   sticky  = table.DisplayMember == member.Name;
                string cellTag = $"<th{(sticky ? " class=\"side\"" : "")}";

                switch (member.Type)
                {
                case BdatMemberType.Scalar:
                case BdatMemberType.Flag:
                    sb.AppendLine($"{cellTag}>{member.Name}</th>");
                    break;

                case BdatMemberType.Array:
                    sb.AppendLine($"{cellTag} colspan=\"{member.ArrayCount}\">{member.Name}</th>");
                    break;
                }
            }

            sb.DecreaseAndAppendLine("</tr>");
            sb.DecreaseAndAppendLine("</thead>");

            foreach (BdatStringItem item in table.Items.Where(x => x != null))
            {
                sb.AppendLineAndIncrease($"<tr id=\"{item.Id}\">");
                sb.AppendLine($"<td>{item.Id}</td>");
                sb.AppendLineAndIncrease("<td>");

                if (item.ReferencedBy.Count > 0)
                {
                    sb.AppendLineAndIncrease("<details>");
                    sb.AppendLine($"<summary>{item.ReferencedBy.Count} refs</summary>");

                    foreach (BdatStringItem a in item.ReferencedBy.OrderBy(x => x.Table.Name).ThenBy(x => x.Id))
                    {
                        string link    = GetLink(table, a.Table, a.Id.ToString());
                        string display = (string)a.Display?.Display ?? a.Id.ToString();

                        if (string.IsNullOrWhiteSpace(display))
                        {
                            display = a.Id.ToString();
                        }

                        sb.AppendLine($"<a href=\"{link}\">{a.Table.Name}#{display}</a>");
                    }

                    sb.DecreaseAndAppendLine("</details>");
                }

                sb.DecreaseAndAppendLine("</td>");

                foreach (BdatStringValue value in item.Values.Values)
                {
                    BdatMember member = value.Member;
                    if (member.Metadata?.Type == BdatFieldType.Hide)
                    {
                        continue;
                    }

                    bool   sticky  = value.Parent.Display == value;
                    string cellTag = $"<td{(sticky ? " class=\"side\"" : "")}>";
                    switch (member.Type)
                    {
                    case BdatMemberType.Scalar:
                    case BdatMemberType.Flag:
                        PrintValue(value, cellTag);

                        break;

                    case BdatMemberType.Array:
                        foreach (BdatStringValue arrValue in value.Array)
                        {
                            PrintValue(arrValue, cellTag);
                        }

                        break;
                    }
                }

                sb.DecreaseAndAppendLine("</tr>");
            }

            sb.DecreaseAndAppendLine("</table>");

            void PrintValue(BdatStringValue value, string cellTag)
            {
                BdatStringItem child = value.Reference;

                if (child != null)
                {
                    string display = child.Display?.DisplayString;
                    if (string.IsNullOrWhiteSpace(display))
                    {
                        display = child.Id.ToString();
                    }

                    string link = GetLink(table, child.Table, child.Id.ToString());
                    sb.AppendLine($"{cellTag}<a href=\"{link}\">{WebUtility.HtmlEncode(display)}</td></a>");
                }
                else
                {
                    sb.AppendLine($"{cellTag}{WebUtility.HtmlEncode(value.DisplayString)}</td>");
                }
            }
        }
예제 #9
0
        public static void ResolveItemRef(BdatStringValue value)
        {
            if (value.Resolved) return;

            BdatStringItem item = value.Parent;
            BdatStringTable table = item.Table;
            BdatStringCollection tables = table.Collection;
            BdatMember member = value.Member;
            BdatFieldInfo field = member.Metadata;

            if (value.Array != null)
            {
                foreach (var element in value.Array)
                {
                    ResolveItemRef(element);
                }

                value.Resolved = true;
                return;
            }

            if (field == null)
            {
                value.Resolved = true;
                return;
            }

            int refId = int.Parse(value.ValueString) + field.Adjust;

            switch (field.Type)
            {
                case BdatFieldType.Message:
                    value.Display = tables[field.RefTable][refId]?["name"].DisplayString;
                    if (string.IsNullOrWhiteSpace(value.DisplayString) && refId > 0)
                    {
                        value.Display = refId.ToString();
                    }
                    break;
                case BdatFieldType.Reference:
                    ApplyRef(field.RefTable);
                    break;
                case BdatFieldType.Item:
                    if (tables.Game == Game.XB2) ApplyRef(BdatStringTools.GetItemTableXb2(refId));
                    if (tables.Game == Game.XB1)
                    {
                        var itemType = (ItemTypeXb1)int.Parse(item[field.RefField].ValueString);
                        ApplyRef(BdatStringTools.GetItemTableXb1(itemType));
                    }
                    if (tables.Game == Game.XBX)
                    {
                        var itemType = (ItemTypeXbx)int.Parse(item[field.RefField].ValueString);
                        ApplyRef(BdatStringTools.GetItemTableXbx(itemType));
                    }

                    break;
                case BdatFieldType.Event:
                    ApplyRef(BdatStringTools.GetEventTable(refId));
                    break;
                case BdatFieldType.EventSetup:
                    ApplyRef(BdatStringTools.GetEventSetupTable(refId));
                    break;
                case BdatFieldType.QuestFlag:
                    ApplyRef(BdatStringTools.GetQuestListTable(refId));
                    break;
                case BdatFieldType.QuestFlagIra:
                    ApplyRef(BdatStringTools.GetQuestListIraTable(refId));
                    break;
                case BdatFieldType.Condition:
                    var conditionType = (ConditionType)int.Parse(item[field.RefField].ValueString);
                    ApplyRef(BdatStringTools.GetConditionTable(conditionType));
                    break;
                case BdatFieldType.Task:
                    var taskType = (TaskType)int.Parse(item[field.RefField].ValueString);
                    ApplyRef(BdatStringTools.GetTaskTable(taskType));
                    break;
                case BdatFieldType.ShopTable:
                    var shopType = (ShopType)int.Parse(item[field.RefField].ValueString);
                    ApplyRef(BdatStringTools.GetShopTable(shopType));
                    break;
                case BdatFieldType.Character:
                    ApplyRef(BdatStringTools.GetCharacterTable(refId));
                    break;
                case BdatFieldType.Enhance:
                    value.Display = BdatStringTools.GetEnhanceCaption(value);
                    break;
                case BdatFieldType.WeatherIdMap:
                    value.Display = BdatStringTools.PrintWeatherIdMap(refId, 13, tables);
                    break;
                case BdatFieldType.PouchBuff:
                    value.Display = GetPouchBuffCaption(value);
                    break;
                case BdatFieldType.Flag:
                    AddFlag(tables, field.RefTable, refId, value);
                    break;
                case BdatFieldType.GameFlag:
                    var flagType = item[field.RefField].ValueString;
                    AddFlag(tables, flagType + "bit", refId, value);
                    break;
                case BdatFieldType.Change:
                    var changeType = (ChangeType)int.Parse(item[field.RefField].ValueString);
                    if (changeType == ChangeType.scenario)
                    {
                        AddFlag(tables, "Scenario", refId, value);
                    }
                    break;
                case BdatFieldType.ItemComment:
                    ApplyRef(item.Id >= 1852 ? "MNU_item_mes_b" : "MNU_item_mes_a");
                    break;
                case BdatFieldType.Layer:
                    ApplyRef(BdatStringTools.GetLayerTable(refId));
                    break;
            }

            if (field.EnumType != null)
            {
                if (field.EnumType.GetCustomAttributes(typeof(FlagsAttribute), false).Length > 0)
                {
                    value.Display = BdatStringTools.PrintEnumFlags(field.EnumType, refId);
                }
                else
                {
                    value.Display = Enum.GetName(field.EnumType, refId);
                }
            }

            value.Resolved = true;

            void ApplyRef(string refTable)
            {
                if (refTable == null || !tables[refTable].ContainsId(refId))
                {
                    value.Display = refId == 0 ? null : refId.ToString();
                    return;
                }

                var reft = tables[refTable][refId].Display;

                if (reft != null)
                {
                    if (!reft.Resolved)
                    {
                        ResolveItemRef(reft);
                    }

                    if (!string.IsNullOrWhiteSpace(reft.DisplayString))
                    {
                        value.Display = reft.Display;
                    }
                }

                value.Reference = tables[refTable][refId];
                tables[refTable][refId].ReferencedBy.Add(value.Parent);
            }
        }