public static MigrationReadyStatus CheckReadyStatusOfMigration(string cookie)
        {
            CharacterTransfer xfer = null;
            ManualResetEvent  mre  = new ManualResetEvent(false);

            DatabaseManager.Shard.GetCharacterTransfers((xfers) =>
            {
                xfer = xfers.FirstOrDefault(k => k.Cookie == cookie);
                mre.Set();
            });
            mre.WaitOne();
            if (xfer == null)
            {
                return(MigrationReadyStatus.NonExistant);
            }
            if (xfer.TransferType != (uint)PackageType.Migrate)
            {
                return(MigrationReadyStatus.NotMigration);
            }
            if (xfer.DownloadTime != null)
            {
                return(MigrationReadyStatus.AlreadyDownloaded);
            }
            if (xfer.CancelTime != null)
            {
                return(MigrationReadyStatus.AlreadyCancelled);
            }
            Character character = null;

            mre = new ManualResetEvent(false);
            DatabaseManager.Shard.GetCharacters(xfer.AccountId, false, new Action <List <Character> >(new Action <List <Character> >((chars) =>
            {
                character = chars.FirstOrDefault(k => k.Id == xfer.PackageSourceId);
                mre.Set();
            })));
            mre.WaitOne();
            if (character == null)
            {
                return(MigrationReadyStatus.CharNotFound);
            }
            if (!character.IsReadOnly)
            {
                return(MigrationReadyStatus.InvalidCharState);
            }
            string packageFilePath = TransferManagerUtil.GetTransferPackageFilePath(cookie, log);

            if (!File.Exists(packageFilePath))
            {
                return(MigrationReadyStatus.PackageFileMissing);
            }
            return(MigrationReadyStatus.Ready);
        }
        public static MigrateCloseResult CloseMigration(PackageMetadata metadata, MigrationCloseType type)
        {
            MigrationReadyStatus readyStatus = CheckReadyStatusOfMigration(metadata.Cookie);

            if (readyStatus != MigrationReadyStatus.Ready)
            {
                return(new MigrateCloseResult());
            }
            CharacterTransfer xfer = null;
            ManualResetEvent  mre  = new ManualResetEvent(false);

            DatabaseManager.Shard.GetCharacterTransfers((xfers) =>
            {
                xfer = xfers.FirstOrDefault(k => k.Cookie == metadata.Cookie);
                mre.Set();
            });
            mre.WaitOne();
            if (xfer.AccountId != metadata.AccountId)
            {
                return(new MigrateCloseResult());
            }
            Character character = null;

            mre = new ManualResetEvent(false);
            DatabaseManager.Shard.GetCharacters(xfer.AccountId, false, new Action <List <Character> >(new Action <List <Character> >((chars) =>
            {
                character = chars.FirstOrDefault(k => k.Id == xfer.PackageSourceId);
                mre.Set();
            })));
            mre.WaitOne();
            string packageFilePath = TransferManagerUtil.GetTransferPackageFilePath(metadata.Cookie, log);

            if (type == MigrationCloseType.Cancel)
            {
                character.IsReadOnly = false;
                DatabaseManager.Shard.SaveCharacter(character, new ReaderWriterLockSlim(), null);
                xfer.CancelTime = (ulong)Time.GetUnixTime();
                DatabaseManager.Shard.SaveCharacterTransfer(xfer, new ReaderWriterLockSlim(), null);
                TransferManagerUtil.DeleteTransferPackageFile(metadata.Cookie, log);
                return(new MigrateCloseResult()
                {
                    Success = true
                });
            }
            else if (type == MigrationCloseType.Download)
            {
                character.IsReadOnly = false;
                character.IsDeleted  = true;
                character.DeleteTime = (ulong)Time.GetUnixTime();
                DatabaseManager.Shard.SaveCharacter(character, new ReaderWriterLockSlim(), null);
                xfer.DownloadTime = (ulong)Time.GetUnixTime();
                DatabaseManager.Shard.SaveCharacterTransfer(xfer, new ReaderWriterLockSlim(), null);
                MigrateCloseResult res = new MigrateCloseResult()
                {
                    Success         = true,
                    SnapshotPackage = File.ReadAllBytes(packageFilePath)
                };
                TransferManagerUtil.DeleteTransferPackageFile(metadata.Cookie, log);
                return(res);
            }
            else
            {
                return(new MigrateCloseResult());
            }
        }