示例#1
0
        public static void Writer(DbDebugItem <int> debug, AbstractDb <int> db)
        {
            var    gdb      = db.ProjectDatabase;
            string filename = ProjectConfiguration.ClientCheevo;

            if (gdb.MetaGrf.GetData(filename) == null)
            {
                Debug.Ignore(() => DbDebugHelper.OnWriteStatusUpdate(ServerDbs.CItems, filename, null, "Achievement table not saved."));
                return;
            }

            BackupEngine.Instance.BackupClient(filename, gdb.MetaGrf);

            StringBuilder builder = new StringBuilder();

            builder.AppendLine("achievement_tbl = {");

            List <ReadableTuple <int> > tuples = gdb.GetDb <int>(ServerDbs.CCheevo).Table.GetSortedItems().ToList();
            ReadableTuple <int>         tuple;

            for (int index = 0, count = tuples.Count; index < count; index++)
            {
                tuple = tuples[index];
                WriteEntry(builder, tuple, index == count - 1);
            }

            builder.AppendLine("}");
            builder.AppendLine();
            builder.AppendLine(ResourceString.Get("AchievementFunction"));

            gdb.MetaGrf.SetData(filename, EncodingService.Ansi.GetBytes(builder.ToString()));

            Debug.Ignore(() => DbDebugHelper.OnWriteStatusUpdate(ServerDbs.CItems, gdb.MetaGrf.FindTkPath(filename), null, "Saving Achievement table."));
        }
示例#2
0
 public override void Open()
 {
     DbDebugHelper.OnSftpUpdate("connecting...");
     _sftp.Connect(_info.Port);
     DbDebugHelper.OnSftpUpdate("connected.");
     _db = new SftpDb(FullPath);
 }
示例#3
0
        private static void _loadDataQuest(AbstractDb <int> db, string file)
        {
            var table = db.Table;

            TextFileHelper.LatestFile = file;

            try {
                foreach (string[] elements in TextFileHelper.GetElementsInt(db.ProjectDatabase.MetaGrf.GetData(file)))
                {
                    int itemId = Int32.Parse(elements[0]);

                    table.SetRaw(itemId, ClientQuestsAttributes.Name, elements[1]);
                    table.SetRaw(itemId, ClientQuestsAttributes.SG, elements[2]);
                    table.SetRaw(itemId, ClientQuestsAttributes.QUE, elements[3]);
                    table.SetRaw(itemId, ClientQuestsAttributes.FullDesc, elements[4]);
                    table.SetRaw(itemId, ClientQuestsAttributes.ShortDesc, elements[5]);
                }

                Debug.Ignore(() => DbDebugHelper.OnLoaded(db.DbSource, db.ProjectDatabase.MetaGrf.FindTkPath(file), db));
            }
            catch (Exception err) {
                Debug.Ignore(() => DbDebugHelper.OnExceptionThrown(db.DbSource, file, db));
                throw new Exception(TextFileHelper.GetLastError(), err);
            }
        }
示例#4
0
        /// <summary>
        /// Reloads the database.
        /// </summary>
        /// <param name="progress">The progress object.</param>
        public void Reload(IProgress progress)
        {
            DbDebugHelper.OnUpdate("Reloading database...");
            OnPreviewReloaded();

            try {
                IOHelper.SetupFileManager();
                Commands.ClearCommands();
                DbPathLocator.ClearStoredFiles();
                ResetAllSettings();

                var dbs = _dbs.Values.ToList();

                for (int i = 0; i < dbs.Count; i++)
                {
                    dbs[i].Clear();
                    DbDebugHelper.OnCleared(dbs[i].DbSource, null, dbs[i]);
                }

                DbDebugHelper.OnUpdate("All database tables have been cleared.");

                for (int i = 0; i < dbs.Count; i++)
                {
                    var db = dbs[i];

                    if (db.CanBeLoaded)
                    {
                        CLHelper.CStart(i);

                        db.LoadDb();

                        if (progress != null)
                        {
                            progress.Progress = (i + 1f) / dbs.Count * 100f;
                            //ErrorHandler.HandleException("Now at " + progress.Progress + "% done.");
                        }

                        CLHelper.CStopAndDisplay(db.DbSource.DisplayName, i);
                    }

                    if (progress != null)
                    {
                        AProgress.IsCancelling(progress);
                    }
                }

                ClearCommands();
            }
            finally {
                DbDebugHelper.OnUpdate("Database reloaded...");
            }

            OnReloaded();
            SdeEditor.Instance.Dispatch(p => p.OnSelectionChanged());
        }
示例#5
0
        private static void _dbClientQuestWrite(SdeDatabase gdb, AbstractDb <int> db, string path)
        {
            if (path == null || gdb.MetaGrf.GetData(path) == null)
            {
                Debug.Ignore(() => DbDebugHelper.OnWriteStatusUpdate(ServerDbs.CQuests, "data\\questid2display.txt", null, "Table not saved."));
                return;
            }

            BackupEngine.Instance.BackupClient(path, gdb.MetaGrf);

            //string tmpFilename = Path.Combine(SdeAppConfiguration.TempPath, Path.GetFileName(path));
            Encoding encoder = EncodingService.DisplayEncoding;

            byte[] tmpBuffer;
            byte[] lineFeedByte       = encoder.GetBytes(SdeStrings.LineFeed);
            byte[] doubleLineFeedByte = encoder.GetBytes(SdeStrings.LineFeed + SdeStrings.LineFeed);

            using (MemoryStream memStream = new MemoryStream()) {
                IEnumerable <ReadableTuple <int> > items = gdb.GetDb <int>(ServerDbs.CQuests).Table.GetSortedItems();

                foreach (ReadableTuple <int> item in items)
                {
                    tmpBuffer = encoder.GetBytes(
                        item.GetValue <int>(ClientQuestsAttributes.Id) + "#" +
                        item.GetValue <string>(ClientQuestsAttributes.Name) + "#" +
                        item.GetValue <string>(ClientQuestsAttributes.SG) + "#" +
                        item.GetValue <string>(ClientQuestsAttributes.QUE) + "#" +
                        "\r\n" + item.GetValue <string>(ClientQuestsAttributes.FullDesc) + "#" +
                        "\r\n" + item.GetValue <string>(ClientQuestsAttributes.ShortDesc) + "#");

                    memStream.Write(tmpBuffer, 0, tmpBuffer.Length);
                    memStream.Write(doubleLineFeedByte, 0, doubleLineFeedByte.Length);
                }

                memStream.Write(lineFeedByte, 0, lineFeedByte.Length);

                tmpBuffer = new byte[memStream.Length];
                Buffer.BlockCopy(memStream.GetBuffer(), 0, tmpBuffer, 0, tmpBuffer.Length);

                //File.WriteAllBytes(tmpFilename, tmpBuffer);
            }

            string copyPath = path;

            try {
                gdb.MetaGrf.SetData(copyPath, tmpBuffer);
            }
            catch (Exception err) {
                ErrorHandler.HandleException(err);
            }

            Debug.Ignore(() => DbDebugHelper.OnWriteStatusUpdate(ServerDbs.CQuests, db.ProjectDatabase.MetaGrf.FindTkPath(path), null, "Saving client table (questdb)."));
        }
示例#6
0
        private static void _saveItemDataToLua(SdeDatabase gdb, string filename, string output)
        {
            if (output == null && gdb.MetaGrf.GetData(filename) == null)
            {
                Debug.Ignore(() => DbDebugHelper.OnWriteStatusUpdate(ServerDbs.CItems, filename, null, "ItemInfo table not saved."));
                return;
            }

            if (output == null)
            {
                BackupEngine.Instance.BackupClient(filename, gdb.MetaGrf);
            }

            StringBuilder builder = new StringBuilder();

            builder.AppendLine("tbl = {");

            List <ReadableTuple <int> > tuples = gdb.GetDb <int>(ServerDbs.CItems).Table.GetSortedItems().ToList();
            ReadableTuple <int>         tuple;

            for (int index = 0, count = tuples.Count; index < count; index++)
            {
                tuple = tuples[index];
                WriteEntry(builder, tuple, index == count - 1);
            }

            builder.AppendLine("}");
            builder.AppendLine();
            builder.AppendLine(ResourceString.Get("ItemInfoFunction"));

            if (output == null)
            {
                gdb.MetaGrf.SetData(filename, EncodingService.Ansi.GetBytes(builder.ToString()));
            }
            else
            {
                string copyPath = Path.Combine(output, Path.GetFileName(filename));

                try {
                    File.WriteAllText(copyPath, builder.ToString(), EncodingService.Ansi);
                }
                catch (Exception err) {
                    ErrorHandler.HandleException(err);
                }
            }

            Debug.Ignore(() => DbDebugHelper.OnWriteStatusUpdate(ServerDbs.CItems, gdb.MetaGrf.FindTkPath(filename), null, "Saving ItemInfo table."));
        }
示例#7
0
        /// <summary>
        /// Saves the database.
        /// </summary>
        /// <param name="ap">The progress object.</param>
        /// <param name="progress"> </param>
        public virtual void Save(AsyncOperation ap, IProgress progress)
        {
            string     dbPath     = GrfPath.GetDirectoryName(ProjectConfiguration.DatabasePath);
            string     subPath    = ProjectConfiguration.DatabasePath.Replace(dbPath, "").TrimStart('\\', '/');
            ServerType serverType = DbPathLocator.GetServerType();

            DbDebugHelper.OnUpdate("Saving tables.");

            MetaGrf.Clear();

            try {
                BackupEngine.Instance.Start(ProjectConfiguration.DatabasePath);

                var dbs = _dbs.Values.ToList();

                IOHelper.SetupFileManager();

                for (int i = 0; i < dbs.Count; i++)
                {
                    var db = dbs[i];
                    db.WriteDb(dbPath, subPath, serverType);

                    if (progress != null)
                    {
                        progress.Progress = AProgress.LimitProgress((i + 1f) / dbs.Count * 100f);
                    }
                }

                foreach (var db in dbs)
                {
                    db.SaveCommandIndex();
                }

                Commands.SaveCommandIndex();
            }
            catch (Exception err) {
                ErrorHandler.HandleException(err);
            }
            finally {
                if (ap != null && progress != null)
                {
                    progress.Progress = ap.ProgressBar.GetIntermediateState("Backup manager");
                }

                BackupEngine.Instance.Stop();
                DbDebugHelper.OnUpdate("Finished saving tables.");
            }
        }
示例#8
0
        private void _map()
        {
            if (_hasBeenMapped)
            {
                return;
            }

            // List all files
            var basePath = GrfPath.GetDirectoryName(_info.Path).TrimEnd('/');

            DbDebugHelper.OnSftpUpdate("listing files...");
            List <ChannelSftp.LsEntry> files = _sftp.GetFileListAdv(basePath);

            DbDebugHelper.OnSftpUpdate("listing " + basePath);

            foreach (var file in files)
            {
                var cur = file.getFilename();

                if (file.getAttrs().isDir() && cur != "." && cur != ".." &&
                    (cur == "re" || cur == "pre-re" || cur == "import"))
                {
                    var subPath = basePath + "/" + cur;
                    DbDebugHelper.OnSftpUpdate("listing " + subPath);

                    List <ChannelSftp.LsEntry> filesSub = _sftp.GetFileListAdv(subPath);

                    foreach (var subfile in filesSub)
                    {
                        if (!subfile.getAttrs().isDir())
                        {
                            _entries[subPath + "/" + subfile.getFilename()] = subfile;
                        }
                    }
                }
                else
                {
                    _entries[basePath + "/" + cur] = file;
                }
            }

            DbDebugHelper.OnSftpUpdate("" + _entries.Count + " files found.");
            _hasBeenMapped = true;
        }
示例#9
0
        public override byte[] ReadAllBytes(string path)
        {
            var temp = _getTempPath();

            FtpUrlInfo urlSource = new FtpUrlInfo(path);
            var        entry     = _entries[urlSource.Path];

            if (_db.Exists(urlSource.Path, entry))
            {
                return(_db.Get(urlSource.Path));
            }

            DbDebugHelper.OnSftpUpdate("downloading " + urlSource.Path);
            _sftp.Get(urlSource.Path, temp);
            DbDebugHelper.OnSftpUpdate("caching " + urlSource.Path);
            _db.Set(temp, urlSource.Path, entry);

            return(File.ReadAllBytes(temp));
        }
示例#10
0
        private static void _loadData <T>(AbstractDb <T> db, string file, DbAttribute attribute, bool allowCutLine = true, bool removeUnderscore = false)
        {
            var table = db.Table;

            TextFileHelper.LatestFile = file;

            try {
                foreach (string[] elements in TextFileHelper.GetElements(db.ProjectDatabase.MetaGrf.GetData(file), allowCutLine))
                {
                    T itemId = (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFrom(elements[0]);
                    table.SetRaw(itemId, attribute, removeUnderscore ? elements[1].Replace("_", " ") : elements[1]);
                }

                Debug.Ignore(() => DbDebugHelper.OnLoaded(db.DbSource, db.ProjectDatabase.MetaGrf.FindTkPath(file), db));
            }
            catch (Exception err) {
                Debug.Ignore(() => DbDebugHelper.OnExceptionThrown(db.DbSource, file, db));
                throw new Exception(TextFileHelper.GetLastError(), err);
            }
        }
示例#11
0
        private static void _loadCardPostfixes(AbstractDb <int> db, byte[] data)
        {
            var table = db.Table;
            DbDebugItem <int> debug = new DbDebugItem <int>(null);

            TextFileHelper.LatestFile = db.ProjectDatabase.MetaGrf.LatestFile;

            foreach (string element in TextFileHelper.GetSingleElement(data))
            {
                try {
                    int itemId = Int32.Parse(element);
                    table.SetRaw(itemId, ClientItemAttributes.IsCard, true, true);
                    table.SetRaw(itemId, ClientItemAttributes.Postfix, true, true);
                }
                catch (Exception err) {
                    if (!debug.ReportException(err))
                    {
                        return;
                    }
                }
            }

            Debug.Ignore(() => DbDebugHelper.OnLoaded(db.DbSource, db.ProjectDatabase.MetaGrf.FindTkPath(db.ProjectDatabase.MetaGrf.LatestFile), db));
        }
示例#12
0
        public override void Copy(string sourceFile, string destFile)
        {
            _map();
            FtpUrlInfo urlSource = new FtpUrlInfo(sourceFile);
            FtpUrlInfo urlDest   = new FtpUrlInfo(destFile);

            if (urlSource.Scheme == "sftp")
            {
                var entry = _entries[urlSource.Path];

                if (_db.Exists(urlSource.Path, entry))
                {
                    var data = _db.Get(urlSource.Path);
                    File.WriteAllBytes(destFile, data);
                }
                else
                {
                    DbDebugHelper.OnSftpUpdate("downloading " + urlSource.Path);
                    _sftp.Get(urlSource.Path, destFile);
                    DbDebugHelper.OnSftpUpdate("caching " + urlSource.Path);
                    _db.Set(destFile, urlSource.Path, entry);
                }
            }
            else
            {
                if (_entries.ContainsKey(urlDest.Path))
                {
                    var entry = _entries[urlDest.Path];

                    if (_db.Exists(urlDest.Path, entry))
                    {
                        byte[] dataDest   = _db.Get(urlDest.Path);
                        byte[] dataSource = File.ReadAllBytes(sourceFile);

                        Crc32Hash hash = new Crc32Hash();

                        if (dataDest.Length == dataSource.Length && hash.ComputeHash(dataDest) == hash.ComputeHash(dataSource))
                        {
                            // do not upload the same file
                        }
                        else
                        {
                            DbDebugHelper.OnSftpUpdate("uploading " + urlDest.Path);
                            _sftp.Put(sourceFile, urlDest.Path);
                            DbDebugHelper.OnSftpUpdate("updating cached version for " + urlDest.Path);
                            var newEntry = _sftp.GetFileListAdv(urlDest.Path)[0];
                            _db.Set(sourceFile, urlDest.Path, newEntry);
                            _entries[urlDest.Path] = newEntry;
                        }
                    }
                    else
                    {
                        DbDebugHelper.OnSftpUpdate("uploading " + urlDest.Path);
                        _sftp.Put(sourceFile, urlDest.Path);
                        DbDebugHelper.OnSftpUpdate("updating cached version for " + urlDest.Path);
                        var newEntry = _sftp.GetFileListAdv(urlDest.Path)[0];
                        _db.Set(sourceFile, urlDest.Path, newEntry);
                        _entries[urlDest.Path] = newEntry;
                    }
                }
                else
                {
                    DbDebugHelper.OnSftpUpdate("uploading new file " + urlDest.Path);
                    _sftp.Put(sourceFile, urlDest.Path);
                }
            }
        }
示例#13
0
        private void _menuItemUpdateClientQuests_Click(object sender, RoutedEventArgs e)
        {
            try {
                var tab = FindTopmostTab();

                if (tab == null)
                {
                    return;
                }

                string file = PathRequest.OpenFileCde("fileName", "iRO-questid2display.txt");

                if (file != null)
                {
                    var db    = ProjectDatabase.GetDb <int>(ServerDbs.CQuests);
                    var table = db.Table;

                    try {
                        table.Commands.BeginNoDelay();

                        foreach (string[] elements in TextFileHelper.GetElementsInt(File.ReadAllBytes(file)))
                        {
                            int itemId = Int32.Parse(elements[0]);
                            var tuple  = table.TryGetTuple(itemId);

                            if (tuple != null)
                            {
                                DbIOClientQuests.SetQuestValue(table, tuple, elements, 1);
                                table.Set(itemId, ClientQuestsAttributes.SG, elements[2]);
                                table.Set(itemId, ClientQuestsAttributes.QUE, elements[3]);
                                DbIOClientQuests.SetQuestValue(table, tuple, elements, 4);
                                DbIOClientQuests.SetQuestValue(table, tuple, elements, 5);
                            }
                            else
                            {
                                ReadableTuple <int> newTuple = new ReadableTuple <int>(itemId, ClientQuestsAttributes.AttributeList);
                                table.Commands.AddTuple(itemId, newTuple);
                                table.Commands.Set(newTuple, ClientQuestsAttributes.Name, elements[1]);
                                table.Commands.Set(newTuple, ClientQuestsAttributes.SG, elements[2]);
                                table.Commands.Set(newTuple, ClientQuestsAttributes.QUE, elements[3]);
                                table.Commands.Set(newTuple, ClientQuestsAttributes.FullDesc, elements[4]);
                                table.Commands.Set(newTuple, ClientQuestsAttributes.ShortDesc, elements[5]);
                            }
                        }

                        var db2 = db.ProjectDatabase.GetMetaTable <int>(ServerDbs.Quests);

                        foreach (var quest in db2.FastItems)
                        {
                            var id    = quest.Key;
                            var tuple = table.TryGetTuple(id);

                            if (tuple != null)
                            {
                                DbIOClientQuests.SetQuestValue(table, tuple, quest.GetValue <string>(ServerQuestsAttributes.QuestTitle), ClientQuestsAttributes.Name.Index);
                            }
                            else
                            {
                                ReadableTuple <int> newTuple = new ReadableTuple <int>(id, ClientQuestsAttributes.AttributeList);
                                table.Commands.AddTuple(id, newTuple);
                                table.Commands.Set(newTuple, ClientQuestsAttributes.Name, quest.GetValue <string>(ServerQuestsAttributes.QuestTitle));
                                table.Commands.Set(newTuple, ClientQuestsAttributes.SG, "SG_FEEL");
                                table.Commands.Set(newTuple, ClientQuestsAttributes.QUE, "QUE_NOIMAGE");
                                table.Commands.Set(newTuple, ClientQuestsAttributes.FullDesc, "...");
                                table.Commands.Set(newTuple, ClientQuestsAttributes.ShortDesc, "");
                            }
                        }

                        Debug.Ignore(() => DbDebugHelper.OnLoaded(db.DbSource, db.ProjectDatabase.MetaGrf.FindTkPath(file), db));
                    }
                    catch (Exception err) {
                        table.Commands.CancelEdit();
                        ErrorHandler.HandleException(err);
                    }
                    finally {
                        table.Commands.End();
                    }
                }
            }
            catch (Exception err) {
                ErrorHandler.HandleException(err);
            }
        }
示例#14
0
 public override void Close()
 {
     DbDebugHelper.OnSftpUpdate("closed.");
     _sftp.Close();
 }
示例#15
0
 public override List <ChannelSftp.LsEntry> GetDirectories(string path)
 {
     path = path.Replace("\\", "/");
     DbDebugHelper.OnSftpUpdate("listing " + path);
     return(_sftp.GetFileListAdv(path).Where(p => p.getAttrs().isDir()).ToList());
 }
示例#16
0
        public static void Loader(AbstractDb <int> db, string file)
        {
            if (file == null)
            {
                Debug.Ignore(() => DbDebugHelper.OnUpdate(db.DbSource, null, "achievement_list table will not be loaded."));
                return;
            }

            LuaList list;

            var table   = db.Table;
            var metaGrf = db.ProjectDatabase.MetaGrf;

            string outputPath = GrfPath.Combine(SdeAppConfiguration.TempPath, Path.GetFileName(file));

            byte[] itemData = metaGrf.GetData(file);

            if (itemData == null)
            {
                Debug.Ignore(() => DbDebugHelper.OnUpdate(db.DbSource, file, "File not found."));
                return;
            }

            File.WriteAllBytes(outputPath, itemData);

            if (!File.Exists(outputPath))
            {
                return;
            }

            if (Methods.ByteArrayCompare(itemData, 0, 4, new byte[] { 0x1b, 0x4c, 0x75, 0x61 }, 0))
            {
                // Decompile lub file
                Lub lub  = new Lub(itemData);
                var text = lub.Decompile();
                itemData = EncodingService.DisplayEncoding.GetBytes(text);
                File.WriteAllBytes(outputPath, itemData);
            }

            DbIOMethods.DetectAndSetEncoding(itemData);

            using (LuaReader reader = new LuaReader(outputPath, DbIOMethods.DetectedEncoding)) {
                list = reader.ReadAll();
            }

            LuaKeyValue itemVariable = list.Variables[0] as LuaKeyValue;

            if (itemVariable != null && itemVariable.Key == "achievement_tbl")
            {
                LuaList items = itemVariable.Value as LuaList;

                if (items != null)
                {
                    foreach (LuaKeyValue item in items.Variables)
                    {
                        _loadEntry(table, item);
                    }
                }
            }
            else
            {
                // Possible copy-paste data
                foreach (LuaKeyValue item in list.Variables)
                {
                    _loadEntry(table, item);
                }
            }

            Debug.Ignore(() => DbDebugHelper.OnLoaded(db.DbSource, metaGrf.FindTkPath(file), db));
        }
示例#17
0
 protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
 {
     DbDebugHelper.DetachEvents();
     base.OnClosing(e);
 }
示例#18
0
        private static void _saveFile(SdeDatabase gdb, string filename, string output, DbAttribute attribute, RequiredCondition <ReadableTuple <int> > condition = null, bool allowReturns = true)
        {
            if (output == null && gdb.MetaGrf.GetData(filename) == null)
            {
                Debug.Ignore(() => DbDebugHelper.OnWriteStatusUpdate(ServerDbs.CItems, filename, null, "Table not saved (" + attribute.GetQueryName() + ")."));
                return;
            }

            if (output == null)
            {
                BackupEngine.Instance.BackupClient(filename, gdb.MetaGrf);
            }

            string   tmpFilename = Path.Combine(SdeAppConfiguration.TempPath, Path.GetFileName(filename));
            Encoding encoder     = EncodingService.DisplayEncoding;

            byte[] tmpBuffer;
            byte[] lineFeedByte       = encoder.GetBytes(SdeStrings.LineFeed);
            byte[] doubleLineFeedByte = encoder.GetBytes(SdeStrings.LineFeed + SdeStrings.LineFeed);

            using (MemoryStream memStream = new MemoryStream()) {
                IEnumerable <ReadableTuple <int> > items = gdb.GetDb <int>(ServerDbs.CItems).Table.GetSortedItems();

                int  previousId = -1;
                bool firstItem  = true;

                foreach (ReadableTuple <int> item in items)
                {
                    if (condition == null || condition(item))
                    {
                        string itemProperty = attribute != null?item.GetRawValue(attribute.Index) as string : null;

                        if (itemProperty != null || attribute == null)
                        {
                            if (attribute == ClientItemAttributes.IdentifiedDisplayName || attribute == ClientItemAttributes.UnidentifiedDisplayName)
                            {
                                itemProperty = itemProperty.Replace(" ", "_");
                            }

                            if (!firstItem)
                            {
                                if (allowReturns)
                                {
                                    if (previousId == (item.GetValue <int>(ClientItemAttributes.Id) - 1))
                                    {
                                        memStream.Write(lineFeedByte, 0, lineFeedByte.Length);
                                    }
                                    else
                                    {
                                        memStream.Write(doubleLineFeedByte, 0, doubleLineFeedByte.Length);
                                    }
                                }
                                else
                                {
                                    memStream.Write(lineFeedByte, 0, lineFeedByte.Length);
                                }
                            }

                            if (attribute == null)
                            {
                                tmpBuffer = encoder.GetBytes(item.GetValue <int>(ClientItemAttributes.Id) + "#");
                            }
                            else
                            {
                                tmpBuffer = encoder.GetBytes(item.GetValue <int>(ClientItemAttributes.Id) + "#" + itemProperty + "#");
                            }

                            memStream.Write(tmpBuffer, 0, tmpBuffer.Length);

                            previousId = item.GetValue <int>(ClientItemAttributes.Id);
                            firstItem  = false;
                        }
                    }
                }

                memStream.Write(lineFeedByte, 0, lineFeedByte.Length);

                tmpBuffer = new byte[memStream.Length];
                Buffer.BlockCopy(memStream.GetBuffer(), 0, tmpBuffer, 0, tmpBuffer.Length);

                File.WriteAllBytes(tmpFilename, tmpBuffer);
            }

            if (output == null)
            {
                var data    = gdb.MetaGrf.GetData(filename);
                var toWrite = File.ReadAllBytes(tmpFilename);

                if (data != null && Methods.ByteArrayCompare(data, toWrite))
                {
                    return;
                }

                gdb.MetaGrf.SetData(filename, toWrite);
            }
            else
            {
                string copyPath = Path.Combine(output, Path.GetFileName(filename));

                try {
                    File.Delete(copyPath);
                    File.Copy(tmpFilename, copyPath);
                    File.Delete(tmpFilename);
                }
                catch (Exception err) {
                    ErrorHandler.HandleException(err);
                }
            }

            Debug.Ignore(() => DbDebugHelper.OnWriteStatusUpdate(ServerDbs.CItems, gdb.MetaGrf.FindTkPath(filename), null, "Saving client table (" + (attribute == null ? "" : attribute.GetQueryName()) + ")."));
        }