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); }
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)});"); }
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); }
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()); }
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); }
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()); }
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}"); }
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>"); }
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>"); } } }
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(); } }
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); } } }