public FieldCorrespondencyFinder(string packFile, string xmlDir) { xmlDirectory = xmlDir; DBTypeMap.Instance.InitializeTypeMap(Directory.GetCurrentDirectory()); // initialize patchFileValues from pack file PackFile pack = new PackFileCodec().Open(packFile); foreach (PackedFile contained in pack.Files) { if (contained.FullPath.StartsWith("db")) { // no need to resolve if it's done already... string tableName = DBFile.Typename(contained.FullPath).Replace("_tables", ""); try { PackedFileDbCodec codec = PackedFileDbCodec.GetCodec(contained); codec.AutoadjustGuid = false; DBFile dbFile = codec.Decode(contained.Data); MappedDataTable table = new MappedDataTable(tableName); ValuesFromPack(table, dbFile); ValuesFromXml(table); mappedTables[tableName] = table; #if DEBUG } catch (Exception e) { Console.Error.WriteLine(e.Message); } #else } catch { }
/* * Insert the previously given values into the db table. * A warning will be printed and no data added if the given data doesn't * fit the db file's structure. */ public override void Execute() { // insert always into packed files at the save to file foreach (PackedFile packed in PackedFiles) { // we'll read from packed, but that is in the source pack; // get or create the db file in the target pack DBFile targetFile = GetTargetFile(packed); foreach (RowValues insertValues in Source.Values) { if (targetFile.CurrentType.Fields.Count == insertValues.Count) { DBRow newRow = targetFile.GetNewEntry(); for (int i = 0; i < newRow.Count; i++) { newRow[i].Value = insertValues[i]; } targetFile.Entries.Add(newRow); } else { Console.WriteLine("Cannot insert: was given {0} values, expecting {1} in {2}", insertValues.Count, targetFile.CurrentType.Fields.Count, packed.FullPath); Console.WriteLine("Values: {0}", string.Join(",", insertValues)); } } // encode and store in target pack PackedFile newPacked = new PackedFile(packed.FullPath, false); newPacked.Data = PackedFileDbCodec.GetCodec(newPacked).Encode(targetFile); SaveTo.Add(newPacked, true); } }
/* * Create an optimized packed file from the given one. */ PackedFile CreateOptimizedFile(PackedFile toOptimize) { PackedFile result = toOptimize; // special handling for db files; leave all others as they are. if (toOptimize.FullPath.StartsWith("db")) { try { DBFile modDbFile = FromPacked(toOptimize); if (modDbFile != null) { DBFile gameDbFile = FindInGamePacks(toOptimize); if (TypesCompatible(modDbFile, gameDbFile)) { DBFileHeader header = new DBFileHeader(modDbFile.Header); DBFile optimizedFile = new DBFile(header, modDbFile.CurrentType); optimizedFile.Entries.AddRange(GetDifferingRows(modDbFile, gameDbFile)); if (optimizedFile.Entries.Count != 0) { result.Data = PackedFileDbCodec.GetCodec(toOptimize).Encode(optimizedFile); } else { result = null; } } } } catch (Exception e) { Console.Error.WriteLine(e); } } return(result); }
/** * <summary>Removes all entries identical between the <paramref name="unoptimizedFile"/> and the <paramref name="referenceFiles"/> from the <paramref name="unoptimizedFile"/>.</summary> * <remarks>This function was intended to be passed a <see cref="PackedFile"/> that contains DB tables. If it is passed a PackedFile without DB tables it will not work properly.</remarks> * * <param name="unoptimizedFile">The <see cref="PackedFile"/> to be optimized. It must contain a DB table for the method to work.</param> * <param name="referenceFiles">A <see cref="List{DBFile}"/> of <see cref="DBFile">DBFiles</see> that should be checked for identical table rows in the <paramref name="unoptimizedFile"/>.</param> * * <returns>A new <see cref="PackedFile"/> that contains the optimized data from the <paramref name="unoptimizedFile"/> or null if the resulting <see cref="PackedFile"/> would be empty.</returns> */ public PackedFile OptimizePackedDBFile(PackedFile unoptimizedFile, List <DBFile> referenceFiles) { PackedFile result = unoptimizedFile; DBFile modDBFile = FromPacked(unoptimizedFile); if (modDBFile != null) { foreach (DBFile file in referenceFiles) { if (TypesCompatible(modDBFile, file)) { modDBFile.Entries.RemoveAll(file.ContainsRow); } } if (modDBFile.Entries.Count != 0) { result.Data = PackedFileDbCodec.GetCodec(unoptimizedFile).Encode(modDBFile); } else { result = null; } } return(result); }
/* * Create db file from the given packed file. * Will not throw an exception on error, but return null. */ DBFile FromPacked(PackedFile packed) { DBFile result = null; try { PackedFileDbCodec codec = PackedFileDbCodec.GetCodec(packed); if (codec != null) { result = codec.Decode(packed.Data); } } catch {} return(result); }
/* * Select all rows matching the where clause (or all in none was given) * and set the given values to all corresponding fields. * Note: If the assignment list contains a non-existing field, * that assignment is ignored without warning. */ public override void Execute() { foreach (PackedFile packed in PackedFiles) { DBFile dbFile = PackedFileDbCodec.Decode(packed); foreach (List <FieldInstance> fieldInstance in dbFile.Entries) { if (whereClause != null && !whereClause.Accept(fieldInstance)) { continue; } AdjustValues(fieldInstance); } packed.Data = PackedFileDbCodec.GetCodec(packed).Encode(dbFile); } }
public void ImportExistingPack(string packFileName) { string modName = PACK_FILE_RE.Replace(Path.GetFileName(packFileName), ""); // trigger creation of backup folder new Mod(modName); MultiMods.Instance.AddMod(modName); PackFile pack = new PackFileCodec().Open(packFileName); foreach (PackedFile packed in pack) { // extract to working_data as binary List <string> extractPaths = new List <string>(); byte[] data = null; if (DBTypeMap.Instance.IsSupported(DBFile.typename(packed.FullPath))) { PackedFileDbCodec codec = PackedFileDbCodec.GetCodec(packed); Codec <DBFile> writerCodec = new ModToolDBCodec(FieldMappingManager.Instance); DBFile dbFile = codec.Decode(packed.Data); using (var stream = new MemoryStream()) { writerCodec.Encode(stream, dbFile); data = stream.ToArray(); } string extractFilename = string.Format("{0}.xml", packed.Name); extractPaths.Add(Path.Combine(ModTools.Instance.InstallDirectory, "raw_data", "db", extractFilename)); extractPaths.Add(Path.Combine(ModTools.Instance.RawDataPath, "EmpireDesignData", "db", extractFilename)); } else { extractPaths.Add(Path.Combine(ModTools.Instance.WorkingDataPath, packed.FullPath)); data = packed.Data; } foreach (string path in extractPaths) { string extractDir = Path.GetDirectoryName(path); if (!Directory.Exists(extractDir)) { Directory.CreateDirectory(extractDir); } File.WriteAllBytes(path, data); } } }
private List <ModLine> ReadPackedField(PackedFile file, string fileName) { if (File.Exists(fileName)) { string key = DBFile.Typename(file.FullPath); DBFileHeader header = PackedFileDbCodec.readHeader(file); string exp = null; if (PackedFileDbCodec.CanDecode(file, out exp)) { PackedFileDbCodec codec = PackedFileDbCodec.GetCodec(file); DBFile f = codec.Decode(file.Data); if (f != null) { if (f.Entries.Count > 0) { //寻找主键字段 List <string> keys = f.CurrentType.Fields.Where(p => p.PrimaryKey).Select(p => p.Name).ToList(); if (keys.Count > 0) { return(f.Entries.Select(line => { ModLine modLine = new ModLine(); modLine.FileName = fileName; modLine.TableName = f.CurrentType.Name; modLine.FieldKeyName = new string[keys.Count]; modLine.FieldKeyValue = new string[keys.Count]; for (int i = 0; i < keys.Count; i++) { modLine.FieldKeyName[i] = keys[i]; modLine.FieldKeyValue[i] = line[keys[i]].Value; } return modLine; }).ToList()); } } } } } return(new List <ModLine>()); }
/* * Delete all entries matching the where clause if any was given, * or all entries if none was given. */ public override void Execute() { if (SaveTo == null) { return; } foreach (PackedFile packed in PackedFiles) { PackedFile result = new PackedFile(packed.FullPath, false); DBFile dbFile = PackedFileDbCodec.Decode(packed); List <DBRow> kept = new List <DBRow>(); foreach (DBRow field in dbFile.Entries) { if (whereClause != null && !whereClause.Accept(field)) { kept.Add(field); } } DBFile newDbFile = new DBFile(dbFile.Header, dbFile.CurrentType); newDbFile.Entries.AddRange(kept); result.Data = PackedFileDbCodec.GetCodec(packed).Encode(newDbFile); SaveTo.Add(result, true); } }