Exemple #1
0
        public async Task <bool> ReOpen(bool readOnly)
        {
            Close();
            Dat = new shared.DatFile();

            return(await OpenAsync(readOnly));
        }
Exemple #2
0
 public void Close()
 {
     try
     {
         if (Dat != null)
         {
             Dat.Flush();
             Dat.Dispose();
             Dat = null;
         }
     }
     catch (Exception e)
     {
         Logger.Write(e.Message);
     }
 }
Exemple #3
0
        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);
            }
        }
Exemple #4
0
 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());
            }
        }
Exemple #6
0
        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());
            }
        }