public async Task <bool> ReOpen(bool readOnly) { Close(); Dat = new shared.DatFile(); return(await OpenAsync(readOnly)); }
public void Close() { try { if (Dat != null) { Dat.Flush(); Dat.Dispose(); Dat = null; } } catch (Exception e) { Logger.Write(e.Message); } }
private async Task <bool> OpenWrite() { try { if (Dat == null) { Dat = new shared.DatFile(); } await Task.Run(() => Dat.Open(Path, false)); return(true); } catch (Exception e) { Logger.Write(e.Message); return(false); } }
public abstract byte[] Data(uint id, shared.DatFile dat, SQLiteConnection con, Subfile subfile, PatchContentType contentType, ref int errors);
public override byte[] Data(uint id, shared.DatFile dat, SQLiteConnection con, Subfile subfile, PatchContentType contentType, ref int errors) { if (!dat.SubfileInfo.ContainsKey(id)) { ++errors; Logger.Write($"файл #{id} не существует в ресурсах игры, пропускаю."); return(null); } var blob = Database.GetBlob(con, id); if (blob == null) { ++errors; Logger.Write($"файл #{id} не удалось прочитать из патча, пропускаю."); return(null); } using (var ms = new MemoryStream()) { using (var sw = new BinaryWriter(ms, Encoding.Unicode)) { if (!subfile.IsValid) { ++errors; return(null); } switch (contentType) { case PatchContentType.Image: for (var i = 0; i < 20; ++i) { sw.Write(subfile.Data[i]); } sw.Write(blob.Length); break; case PatchContentType.Sound: for (var i = 0; i < 4; ++i) { sw.Write(subfile.Data[i]); } sw.Write(blob.Length - 8); break; case PatchContentType.Texture: // TODO - in case of modified width/height for (var i = 0; i < 24; ++i) { sw.Write(subfile.Data[i]); } blob = blob.Skip(128).ToArray(); break; } sw.Write(blob); } return(ms.ToArray()); } }
public override byte[] Data(uint id, shared.DatFile dat, SQLiteConnection con, Subfile subfile, PatchContentType contentType, ref int errors) { if (!dat.SubfileInfo.ContainsKey(id)) { ++errors; Logger.Write($"файл #{id} не существует в ресурсах игры, пропускаю."); return(null); } var fragments = Database.GetContent(con, id); if (fragments.Count == 0) { ++errors; Logger.Write($"файл #{id} пуст, пропускаю."); return(null); } if (!subfile.IsValid) { ++errors; return(null); } var orig = new TextSubfile(subfile.Data); if (!orig.IsValid) { ++errors; Logger.Write($"ошибка чтения файла #{id}, пропускаю весь файл."); return(null); } var skippedFragmentsCount = fragments.Count(fragment => !orig.Body.ContainsKey(fragment.Key)); if (skippedFragmentsCount == fragments.Count) { ++errors; Logger.Write($"ни один фрагмент не подходит для перезаписи файла #{id}, пропускаю весь файл."); return(null); } if (skippedFragmentsCount > 0) { Logger.Write($"{skippedFragmentsCount} неопознанных фрагментов в патче для файла #{id} будет пропущено."); } using (var ms = new MemoryStream()) { using (var sw = new BinaryWriter(ms, Encoding.Unicode)) { //Logger.Write($"Кек #{orig.Head.Unknown}"); sw.Write(id); sw.Write(orig.Head.Unknown); //sw.Write(0); sw.Write(orig.Head.Unknown2); ByteOrShort(sw, orig.Head.Fragments); var missingFragmentsCount = 0; foreach (var body in orig.Body) { // detect possible errors var useDefault = false; // patch does not contain data for this fragment if (!fragments.ContainsKey(body.Key)) { missingFragmentsCount++; useDefault = true; Logger.Write($"файл #{id}, фрагмент #{body.Key} - отсутствует в патче, использую оригинал."); } // patch fragment args contain error if (!useDefault && fragments[body.Key].IsArgsError) { missingFragmentsCount++; useDefault = true; Logger.Write($"файл #{id}, фрагмент #{body.Key} - ошибка в строке аргументов, использую оригинал."); } // patch fragment args order contains error if (!useDefault && fragments[body.Key].IsOrderError) { missingFragmentsCount++; useDefault = true; Logger.Write($"файл #{id}, фрагмент #{body.Key} - ошибка в строке порядка, использую оригинал."); } // patch fragment text contain error if (!useDefault && !fragments[body.Key].IsValid) { missingFragmentsCount++; useDefault = true; Logger.Write($"файл #{id}, фрагмент #{body.Key} - ошибка в содержимом, использую оригинал."); } var pieces = useDefault ? body.Value.Pieces : fragments[body.Key].Content.Split(new[] { "<--DO_NOT_TOUCH!-->" }, StringSplitOptions.None); // patch args order was intentionally emptied, force it if (!useDefault && fragments[body.Key].ArgsOrder.Length == 0 && fragments[body.Key].Args.Length > 0 && pieces.Length == 1) { fragments[body.Key].IsDefaultOrder = false; } // broken relation between args count and their plant holes if (!useDefault && (!fragments[body.Key].IsDefaultOrder && fragments[body.Key].ArgsOrder.Length != pieces.Length - 1 || fragments[body.Key].IsDefaultOrder && fragments[body.Key].Args.Length != pieces.Length - 1)) { missingFragmentsCount++; useDefault = true; pieces = body.Value.Pieces; Logger.Write($"файл #{id}, фрагмент #{body.Key} - ошибка в строке порядка, использую оригинал."); } // write token sw.Write(body.Key); // write pieces sw.Write(pieces.Length); foreach (var piece in pieces) { var length = (short)piece.Length; ByteOrShort(sw, length); sw.Write(Encoding.Unicode.GetBytes(piece)); } if (useDefault) { var args = body.Value.Arguments; sw.Write(args.Length); foreach (var arg in args) { sw.Write(arg); } } else { if (fragments[body.Key].IsDefaultOrder) { // use patch default args (ignore patch args order or empty patch args order) var args = fragments[body.Key].Args; sw.Write(args.Length); foreach (var arg in args) { sw.Write(arg); } } else { #if DEBUG if (fragments[body.Key].IsExtraOrder) { Logger.Write($"фрагмент #{body.Key} из файла #{id} - порядок аргументов длиннее исходного."); } #endif // use patch alt args order sw.Write(fragments[body.Key].ArgsOrder.Length); foreach (var ord in fragments[body.Key].ArgsOrder) { sw.Write(fragments[body.Key].Args[ord - 1]); } } } // use original variables var vars = body.Value.Variables; sw.Write((byte)vars.Length); foreach (var pack in vars) { sw.Write(pack.Length); foreach (var rice in pack) { var length = (short)rice.Length; ByteOrShort(sw, length); sw.Write(Encoding.Unicode.GetBytes(rice)); } } } if (missingFragmentsCount > 0) { Logger.Write( $"{missingFragmentsCount} из {orig.Head.Fragments} фрагментов в файле #{id} не изменились."); } } return(ms.ToArray()); } }