private static BdatStringTable ReadTable(byte[] file, int offset)
        {
            if (BitConverter.ToUInt32(file, offset) != 0x54414442)
            {
                return(null);
            }

            int namesOffset = BitConverter.ToUInt16(file, offset + 6);
            var tableName   = Stuff.GetUTF8Z(file, offset + namesOffset);
            var members     = BdatTable.ReadTableMembers(file, offset);

            var table = new BdatStringTable
            {
                Name    = tableName,
                BaseId  = BitConverter.ToUInt16(file, offset + 18),
                Members = members,
                Items   = ReadItems(file, offset, members)
            };

            int id = table.BaseId;

            foreach (BdatStringItem item in table.Items)
            {
                item.Table = tableName;
                item.Id    = id++;
            }

            return(table);
        }
예제 #2
0
        private static string CreateTableQuery(string schemaName, BdatStringTable table)
        {
            List <string> columns = new List <string>();

            columns.Add("\"row_id\" INTEGER");

            foreach (BdatMember member in table.Members)
            {
                string memberType = "";
                switch (member.ValType)
                {
                case BdatValueType.UInt8:
                case BdatValueType.Int8:
                case BdatValueType.Int16:
                    memberType = "SMALLINT";
                    break;

                case BdatValueType.UInt16:
                case BdatValueType.Int32:
                    memberType = "INTEGER";
                    break;

                case BdatValueType.UInt32:
                    memberType = "BIGINT";
                    break;

                case BdatValueType.String:
                    memberType = "TEXT";
                    break;

                case BdatValueType.FP32:
                    memberType = "NUMERIC";
                    break;
                }

                switch (member.Type)
                {
                case BdatMemberType.Flag:
                    memberType = "BOOL";
                    break;

                case BdatMemberType.Array:
                    memberType += "[]";
                    break;
                }

                columns.Add($"\"{member.Name}\" {memberType}");
            }

            return($"CREATE TABLE {schemaName}.\"{table.Name}\" ({String.Join(",", columns)});");
        }
예제 #3
0
        public static BdatStringCollection DeserializeTables(BdatTables tables, IProgressReport progress = null)
        {
            var collection = new BdatStringCollection {
                Bdats = tables
            };

            progress?.LogMessage("Parsing BDAT tables");
            progress?.SetTotal(tables.Tables.Length);

            foreach (BdatTable table in tables.Tables)
            {
                var items = new BdatStringItem[table.ItemCount];

                var stringTable = new BdatStringTable
                {
                    Collection = collection,
                    Name       = table.Name,
                    BaseId     = table.BaseId,
                    Members    = table.Members,
                    Items      = items,
                    Filename   = table.Filename
                };

                if (tables.DisplayFields.TryGetValue(table.Name, out string displayMember))
                {
                    stringTable.DisplayMember = displayMember;
                }

                for (int i = 0; i < table.ItemCount; i++)
                {
                    BdatStringItem item = ReadItem(table, i);
                    item.Table = stringTable;
                    item.Id    = table.BaseId + i;

                    if (displayMember != null)
                    {
                        item.Display = item[displayMember];
                    }

                    items[i] = item;
                }

                collection.Add(stringTable);
                progress?.ReportAdd(1);
            }

            return(collection);
        }
예제 #4
0
        public static void PrintIndex(BdatStringCollection bdats, string htmlDir)
        {
            var sb = new Indenter(2);

            sb.AppendLine("<!DOCTYPE html>");
            sb.AppendLineAndIncrease("<html>");
            sb.AppendLineAndIncrease("<head>");
            sb.AppendLine("<meta charset=\"utf-8\" />");
            sb.AppendLine("<title>Xenoblade 2</title>");
            sb.DecreaseAndAppendLine("</head>");

            sb.AppendLineAndIncrease("<body>");
            sb.AppendLine("<h1>Xenoblade 2 data tables</h1>");
            sb.AppendLine($"<p>{IndexText}</p>");
            sb.AppendLine("<a href=\"chbtlrewards.html\">Challenge Battle Rewards</a><br/>");
            sb.AppendLine("<h2><a href=\"bdat\\index.html\">Complete table list</a></h2>");

            string prefix = bdats.Game.ToString().ToLower();

            if (!File.Exists($"{prefix}_tableDisplay.csv"))
            {
                return;
            }
            using (var stream = new FileStream($"{prefix}_tableDisplay.csv", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                using (var reader = new StreamReader(stream))
                {
                    IEnumerable <BdatFriendlyInfo> csv = new CsvReader(reader).GetRecords <BdatFriendlyInfo>();
                    IOrderedEnumerable <IGrouping <string, BdatFriendlyInfo> > grouped = csv.GroupBy(x => x.Group).OrderBy(x => x.Key);

                    foreach (IGrouping <string, BdatFriendlyInfo> group in grouped)
                    {
                        sb.AppendLine($"<h2>{group.Key ?? "Other"}</h2>");

                        foreach (BdatFriendlyInfo tableInfo in group.OrderBy(x => x.Display))
                        {
                            BdatStringTable table = bdats[tableInfo.TableName];
                            string          path  = Path.Combine("bdat", table.Filename ?? "", table.Name) + ".html";
                            sb.AppendLine($"<a href=\"{path}\">{tableInfo.Display}</a><br/>");
                        }
                    }
                }
            sb.DecreaseAndAppendLine("</body>");
            sb.DecreaseAndAppendLine("</html>");

            string filename = Path.Combine(htmlDir, "index.html");

            File.WriteAllText(filename, sb.ToString());
        }
예제 #5
0
        private static List <Enemy> ReadBdatTables(BdatStringCollection bdats)
        {
            BdatStringTable enemyTable = bdats.Tables["BTL_enelist"];

            var enemies = new List <Enemy>();

            foreach (BdatStringItem item in enemyTable.Items)
            {
                Enemy enemy = TryGetEnemy(item);

                if (enemy != null)
                {
                    enemies.Add(enemy);
                }
            }

            return(enemies);
        }
예제 #6
0
        public static string PrintTable(BdatStringTable table)
        {
            var json = new JArray();

            foreach (BdatStringItem item in table.Items.Where(x => x != null))
            {
                var itemObj = new JObject();
                itemObj["id"] = item.Id;

                foreach (BdatMember member in table.Members)
                {
                    switch (member.Type)
                    {
                    case BdatMemberType.Scalar:
                        string value = item[member.Name].ValueString;
                        itemObj[member.Name] = JToken.FromObject(ParseValue(value, member.ValType));
                        break;

                    case BdatMemberType.Flag:
                        itemObj[member.Name] = bool.Parse(item[member.Name].ValueString);
                        break;

                    case BdatMemberType.Array:
                        var array = new JArray();
                        itemObj[member.Name] = array;

                        foreach (string val in (string[])item[member.Name].Value)
                        {
                            array.Add(ParseValue(val, member.ValType));
                        }

                        break;
                    }
                }

                json.Add(itemObj);
            }


            return(json.ToString());
        }
예제 #7
0
        public static string GetLink(BdatStringTable table, BdatStringTable childTable, string childId)
        {
            string path = string.Empty;

            if (table.Filename == null && childTable.Filename != null)
            {
                path = $"{childTable.Filename}/";
            }

            if (table.Filename != null && childTable.Filename == null)
            {
                path = "../";
            }

            if (table.Filename != null && childTable.Filename != null && table.Filename != childTable.Filename)
            {
                path = $"../{childTable.Filename}/";
            }

            return($"{path}{childTable.Name}.html#{childId}");
        }
예제 #8
0
        public static void PrintTable(BdatStringCollection tables, BdatInfo info, string tableName, Indenter sb)
        {
            BdatStringTable table = tables[tableName];

            sb.AppendLineAndIncrease("<table border=\"1\">");
            sb.AppendLineAndIncrease("<thead>");
            sb.AppendLineAndIncrease("<tr>");
            sb.AppendLine("<th>ID</th>");
            sb.AppendLine("<th>Referenced By</th>");

            foreach (BdatMember member in table.Members)
            {
                if (info.FieldInfo.TryGetValue((tableName, member.Name), out var field))
                {
                    if (field.Type == BdatFieldType.Hide)
                    {
                        continue;
                    }
                }
                switch (member.Type)
                {
                case BdatMemberType.Scalar:
                case BdatMemberType.Flag:
                    sb.AppendLine($"<th>{member.Name}</th>");
                    break;

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

            sb.DecreaseAndAppendLine("</tr>");
            sb.DecreaseAndAppendLine("</thead>");
            int id = table.BaseId;

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

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

                    foreach (var a in item.ReferencedBy)
                    {
                        var    link    = GetLink(table, tables[a.Table], a.Id.ToString());
                        string display = a.Id.ToString();

                        if (info.DisplayFields.TryGetValue(a.Table, out var displayField))
                        {
                            var child = BdatStringTools.ReadValue(a.Table, a.Id, displayField, tables, info);
                            if (!string.IsNullOrWhiteSpace(child.value))
                            {
                                display = child.value;
                            }
                        }

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

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

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

                foreach (BdatMember member in table.Members)
                {
                    if (info.FieldInfo.TryGetValue((tableName, member.Name), out var field))
                    {
                        if (field.Type == BdatFieldType.Hide)
                        {
                            continue;
                        }
                    }

                    switch (member.Type)
                    {
                    case BdatMemberType.Scalar:
                    case BdatMemberType.Flag:
                        var val = BdatStringTools.ReadValue(tableName, id, member.Name, tables, info);
                        if (val.childTable != null)
                        {
                            var link = GetLink(table, tables[val.childTable], val.childId);
                            sb.AppendLine($"<td><a href=\"{link}\">{val.value}</td></a>");
                        }
                        else
                        {
                            sb.AppendLine($"<td>{val.value}</td>");
                        }
                        break;

                    case BdatMemberType.Array:
                        var arr = (string[])item.Values[member.Name];
                        foreach (string value in arr)
                        {
                            sb.AppendLine($"<td>{value}</td>");
                        }
                        break;
                    }
                }

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

            sb.DecreaseAndAppendLine("</table>");
        }
예제 #9
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>");
                }
            }
        }
예제 #10
0
        private static void PrintTable(BdatStringTable table, NpgsqlConnection conn, string schemaName)
        {
            List <string> memberNames = (from member in table.Members select member.Name).ToList();

            memberNames.Add("row_id");

            string columns = String.Join(",", from member in memberNames select $"\"{member}\"");
            string values  = String.Join(",", from member in memberNames select $"@{member}");

            string query = $"INSERT INTO {schemaName}.\"{table.Name}\" ({columns}) VALUES ({values})";

            foreach (BdatStringItem item in table.Items.Where(x => x != null))
            {
                NpgsqlCommand cmd = new NpgsqlCommand();
                cmd.Connection  = conn;
                cmd.CommandText = query;

                var param = cmd.CreateParameter();
                param.ParameterName = "row_id";
                param.Value         = item.Id;
                cmd.Parameters.Add(param);

                foreach (BdatMember member in table.Members)
                {
                    var parameter = cmd.CreateParameter();
                    parameter.ParameterName = member.Name;

                    switch (member.Type)
                    {
                    case BdatMemberType.Scalar:
                        string value = item[member.Name].ValueString;
                        parameter.Value = ParseValue(value, member.ValType);
                        break;

                    case BdatMemberType.Flag:
                        parameter.Value = bool.Parse(item[member.Name].ValueString);
                        break;

                    case BdatMemberType.Array:
                        List <object> array = new List <object>();

                        foreach (string val in (string[])item[member.Name].Value)
                        {
                            array.Add(ParseValue(val, member.ValType));
                        }

                        switch (member.ValType)
                        {
                        case BdatValueType.UInt8:
                        case BdatValueType.UInt16:
                        case BdatValueType.UInt32:
                        case BdatValueType.Int8:
                        case BdatValueType.Int16:
                        case BdatValueType.Int32:
                            parameter.Value = array.Select(k => (long)k).ToList();
                            break;

                        case BdatValueType.String:
                            parameter.Value = array.Select(k => (string)k).ToList();
                            break;

                        case BdatValueType.FP32:
                            parameter.Value = array.Select(k => (float)k).ToList();
                            break;
                        }
                        break;
                    }
                    cmd.Parameters.Add(parameter);
                }
                cmd.ExecuteNonQuery();
            }
        }
예제 #11
0
        public static void PrintAllTables(BdatStringCollection bdats, string schemaName, IProgressReport progress = null)
        {
            string dbName;
            string dbUsername;
            string dbPassword;

            Console.Write("Enter Database Name: ");
            dbName = Console.ReadLine();

            Console.Write("Enter User Name: ");
            dbUsername = Console.ReadLine();

            Console.Write("Enter User Password: "******"Host=localhost;Username={dbUsername};Password={dbPassword};Database={dbName};";

            using (NpgsqlConnection conn = new NpgsqlConnection(connString))
            {
                try
                {
                    conn.Open();
                }
                catch (PostgresException exception)
                {
                    if (exception.SqlState == "28P01")
                    {
                        Console.WriteLine($"Password authentication for user {dbUsername} failed.");
                    }
                    if (exception.SqlState == "3D000")
                    {
                        Console.WriteLine($"Database {dbName} does not exist.");
                    }
                    Environment.Exit(1);
                }

                using (NpgsqlCommand cmd = new NpgsqlCommand())
                {
                    cmd.Connection  = conn;
                    cmd.CommandText = $"CREATE SCHEMA {schemaName};";
                    try
                    {
                        cmd.ExecuteNonQuery();
                    }
                    catch (PostgresException exception)
                    {
                        if (exception.SqlState == "42P06")
                        {
                            Console.WriteLine($"Schema name {schemaName} is already in use. Delete the schema and retry or provide a different schema name.");
                            Environment.Exit(1);
                        }
                    }
                }

                progress?.LogMessage("Writing BDAT tables to postgresql database");
                progress?.SetTotal(bdats.Tables.Count);

                foreach (string tableName in bdats.Tables.Keys)
                {
                    BdatStringTable table = bdats[tableName];

                    string createQuery = CreateTableQuery(schemaName, table);

                    using (var cmd = new NpgsqlCommand())
                    {
                        cmd.Connection  = conn;
                        cmd.CommandText = createQuery;
                        cmd.ExecuteNonQuery();
                    }

                    PrintTable(table, conn, schemaName);
                    progress?.ReportAdd(1);
                }
            }
        }