public IDBCDStorage ApplyingHotfixes(HotfixReader hotfixReader, HotfixReader.RowProcessor processor) { var mutableStorage = this.storage.ToDictionary(k => k.Key, v => v.Value); hotfixReader.ApplyHotfixes(mutableStorage, this.reader, processor); return(new DBCDStorage <T>(this.reader, new ReadOnlyDictionary <int, T>(mutableStorage), this.info)); }
public void TestHotfixApplying() { DBCD dbcd = new DBCD(dbcProvider, githubDBDProvider); var storage = dbcd.Load("ItemSparse"); var hotfix = new HotfixReader("hotfix.bin"); var countBefore = storage.Count; storage = storage.ApplyingHotfixes(hotfix); var countAfter = storage.Count; System.Console.WriteLine($"B: {countBefore} => A: {countAfter}"); }
public static async void Load() { if (!Directory.Exists(GetDBCPath())) { Trace.WriteLine($"DBC folder \"{ GetDBCPath() }\" not found"); return; } else { Trace.WriteLine($"DBC folder \"{ GetDBCPath() }\" found"); } HotfixReader hotfixReader = null; try { hotfixReader = new HotfixReader(GetHotfixCachePath()); Trace.WriteLine($"Hotfix cache {GetHotfixCachePath()} found!"); } catch (Exception) { Trace.WriteLine($"Hotfix cache {GetHotfixCachePath()} cannot be loaded, ignoring!"); } Trace.WriteLine("File name LoadTime Record count"); Trace.WriteLine("---------------------------------------------------------------------"); Parallel.ForEach(typeof(DBC).GetProperties(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic), dbc => { Type type = dbc.PropertyType.GetGenericArguments()[0]; if (!type.IsClass) { return; } var startTime = DateTime.Now; var attr = type.GetCustomAttribute <DBFileAttribute>(); if (attr == null) { return; } var times = new List <long>(); var instanceType = typeof(Storage <>).MakeGenericType(type); var countGetter = instanceType.GetProperty("Count").GetGetMethod(); dynamic instance = Activator.CreateInstance(instanceType, $"{ GetDBCPath(attr.FileName) }.db2"); var recordCount = (int)countGetter.Invoke(instance, new object[] { }); try { var db2Reader = new DBReader($"{ GetDBCPath(attr.FileName) }.db2"); if (hotfixReader != null) { hotfixReader.ApplyHotfixes(instance, db2Reader); } dbc.SetValue(dbc.GetValue(null), instance); } catch (TargetInvocationException tie) { if (tie.InnerException is ArgumentException) { throw new ArgumentException($"Failed to load {attr.FileName}.db2: {tie.InnerException.Message}"); } throw; } var endTime = DateTime.Now; var span = endTime.Subtract(startTime); Trace.WriteLine($"{ attr.FileName.PadRight(33) } { TimeSpan.FromTicks(span.Ticks).ToString().PadRight(28) } { recordCount.ToString().PadRight(19) }"); }); await Task.WhenAll(Task.Run(() => { if (AreaTable != null) { foreach (var db2Info in AreaTable) { if (db2Info.Value.ParentAreaID != 0 && !Zones.ContainsKey(db2Info.Value.ParentAreaID)) { Zones.Add(db2Info.Value.ParentAreaID, db2Info.Value.ZoneName); } } } }), Task.Run(() => { if (MapDifficulty != null) { foreach (var mapDifficulty in MapDifficulty) { int difficultyID = 1 << mapDifficulty.Value.DifficultyID; if (MapSpawnMaskStores.ContainsKey(mapDifficulty.Value.MapID)) { MapSpawnMaskStores[mapDifficulty.Value.MapID] |= difficultyID; } else { MapSpawnMaskStores.Add(mapDifficulty.Value.MapID, difficultyID); } if (!MapDifficultyStores.ContainsKey(mapDifficulty.Value.MapID)) { MapDifficultyStores.Add(mapDifficulty.Value.MapID, new List <int>() { mapDifficulty.Value.DifficultyID }); } else { MapDifficultyStores[mapDifficulty.Value.MapID].Add(mapDifficulty.Value.DifficultyID); } } } }), Task.Run(() => { if (CriteriaTree != null && Achievement != null) { ICollection <AchievementEntry> achievementLists = Achievement.Values; var achievements = achievementLists.GroupBy(achievement => achievement.CriteriaTree) .ToDictionary(group => group.Key, group => group.ToList()); foreach (var criteriaTree in CriteriaTree) { string result = ""; uint criteriaTreeID = criteriaTree.Value.Parent > 0 ? criteriaTree.Value.Parent : (uint)criteriaTree.Key; List <AchievementEntry> achievementList; if (achievements.TryGetValue(criteriaTreeID, out achievementList)) { foreach (var achievement in achievementList) { result = $"AchievementID: {achievement.ID} Description: \"{ achievement.Description }\""; } } if (!CriteriaStores.ContainsKey((ushort)criteriaTree.Value.CriteriaID)) { if (criteriaTree.Value.Description != string.Empty) { result += $" - CriteriaDescription: \"{criteriaTree.Value.Description }\""; } CriteriaStores.Add((ushort)criteriaTree.Value.CriteriaID, result); } else { CriteriaStores[(ushort)criteriaTree.Value.CriteriaID] += $" / CriteriaDescription: \"{ criteriaTree.Value.Description }\""; } } } }), Task.Run(() => { if (Faction != null && FactionTemplate != null) { foreach (var factionTemplate in FactionTemplate) { if (Faction.ContainsKey(factionTemplate.Value.Faction)) { FactionStores.Add((uint)factionTemplate.Key, Faction[factionTemplate.Value.Faction]); } } } }), Task.Run(() => { if (SpellEffect != null) { foreach (var effect in SpellEffect) { var tuple = Tuple.Create((uint)effect.Value.SpellID, (uint)effect.Value.EffectIndex); SpellEffectStores[tuple] = effect.Value; } } }), Task.Run(() => { if (PhaseXPhaseGroup != null) { foreach (var phase in PhaseXPhaseGroup) { if (!Phases.ContainsKey(phase.Value.PhaseGroupID)) { Phases.Add(phase.Value.PhaseGroupID, new List <ushort>() { phase.Value.PhaseID }); } else { Phases[phase.Value.PhaseGroupID].Add(phase.Value.PhaseID); } } } })); }
public IDBCDStorage ApplyingHotfixes(HotfixReader hotfixReader) { return(this.ApplyingHotfixes(hotfixReader, null)); }
public static void Execute(string filter = null) { var dbcd = new DBCD.DBCD(new DBCProvider(dbPath), new DBDProvider(definitionsPath)); var build = "8.3.0.34220"; var connectionString = new SqlConnectionStringBuilder { InitialCatalog = "wow", DataSource = "(local)", IntegratedSecurity = true }.ToString(); using var connection = new SqlConnection(connectionString); connection.Open(); var server = new Server(); var database = server.Databases["wow"]; // The DBCache which stores downloaded / patched database records from the server side Console.WriteLine("Loading in hotfix cache..."); var hotfix = new HotfixReader(Path.Combine(cachePath, "DBCache.bin")); var caches = Directory.EnumerateFiles(cachePath, "DBCache.bin*.tmp").ToList(); hotfix.CombineCaches(caches.ToArray()); Console.WriteLine("Loading tables.."); foreach (var databaseFile in Directory.EnumerateFiles(dbPath, "*.db?", SearchOption.TopDirectoryOnly)) { Console.WriteLine(); var name = Path.GetFileNameWithoutExtension(databaseFile); if (name.StartsWith("UnitTest", StringComparison.OrdinalIgnoreCase)) { continue; } if (!string.IsNullOrWhiteSpace(filter) && !filter.Contains(name, StringComparison.OrdinalIgnoreCase)) { continue; } var storage = dbcd.Load(name, build, Locale.EnUS).ApplyingHotfixes(hotfix); DBCDRow item = storage.Values.FirstOrDefault(); if (item == null) { Console.WriteLine(name + ": **EMPTY**"); continue; } Console.WriteLine(name); Console.WriteLine(string.Join("", Enumerable.Repeat("=", name.Length))); using var table = new DataTable(name); for (var j = 0; j < storage.AvailableColumns.Length; ++j) { string fieldname = storage.AvailableColumns[j]; var field = item[fieldname]; var isEndOfRecord = j == storage.AvailableColumns.Length - 1; if (field is Array a) { for (var i = 0; i < a.Length; i++) { var isEndOfArray = a.Length - 1 == i; Console.Write($"{fieldname}[{i}]"); if (!isEndOfArray) { Console.Write(","); } table.Columns.Add(new DataColumn(fieldname + "_" + i) { DataType = a.GetType().GetElementType() }); } } else { var column = new DataColumn(fieldname) { DataType = field.GetType() }; table.Columns.Add(column); if (fieldname.Equals("id", StringComparison.OrdinalIgnoreCase)) { table.PrimaryKey = new[] { column }; } Console.Write(fieldname); } if (!isEndOfRecord) { Console.Write(","); } } database.CreateTableSchema(table); // Process rows foreach (var row in storage.Values) { var dataRow = table.NewRow(); foreach (var fieldName in storage.AvailableColumns) { var value = row[fieldName]; if (value is Array a) { for (var j = 0; j < a.Length; j++) { var arrayValue = a.GetValue(j).ToString(); // if (searchValues.Contains(arrayValue)) // { // Console.ForegroundColor = ConsoleColor.Yellow; // Console.WriteLine($"Found matching record: {table.TableName}#{row.ID}"); // Console.ResetColor(); // } dataRow[fieldName + "_" + j] = arrayValue; } } else { dataRow[fieldName] = value; } } table.Rows.Add(dataRow); } // Bulk import the data var bulk = new SqlBulkCopy(connection); bulk.DestinationTableName = table.TableName; bulk.WriteToServer(table); Console.WriteLine(); } }