ACR_ServerCommunicator.ServerVaultConnector.OnSynchronizeAccountFromVault C# (CSharp) Method

OnSynchronizeAccountFromVault() private static method

Synchronize new files from the vault storage provider. The SyncPath specifies the path to download changed files from the vault storage provider to. It may be populated with existing files, and only newer files should be transferred from the vault storage provider. This function is called from the transfer synchronization thread.
private static OnSynchronizeAccountFromVault ( string AccountName, string SyncPath, IntPtr Context ) : int
AccountName string Supplies the account name.
SyncPath string Supplies the path to synchronize files to /// from the vault. Existing files should be datestamp compared with /// the vault before being replaced. File are downloaded from the /// vault, not uploaded, with this routine.
Context System.IntPtr Supplies a context handle.
return int
        private static int OnSynchronizeAccountFromVault(string AccountName, string SyncPath, IntPtr Context)
        {
            try
            {
                //
                // Pass through to the default implementation if the connection
                // string is not defined in the database.
                //

                if (String.IsNullOrEmpty(StoreConnectionString))
                    return 1;

                string OriginalAccountName = AccountName;

                //
                // Canonicalize names to lowercase as the file store may be
                // case sensitive and maintaining a mapping table in the
                // database is problematic since the first save for a new
                // account may be observed before the players record for
                // that player is created (and a player could log in to two
                // servers simultaneously and create orphaned records that
                // way, or similarly during a database outage, etc.).
                //

                AccountName = AccountName.ToLowerInvariant();

                try
                {
                    bool DirCreated = false;
                    FileStoreDirectory StoreDirectory = Container.GetDirectoryReference(AccountName);

                    IEnumerable<string> FsFiles = null;
                    Dictionary<string, FileStoreFile> StoreFiles = new Dictionary<string, FileStoreFile>();

                    //
                    // Build an index of all files in the file store vault.
                    //

                    foreach (FileStoreFile StoreFile in StoreDirectory.GetFiles())
                    {
                        string[] Segments = StoreFile.Uri.Segments;

                        if (Segments.Length == 0)
                            continue;

                        string CharacterFileName = Segments[Segments.Length - 1].ToLowerInvariant();

                        if (!CharacterFileName.EndsWith(".bic"))
                            continue;

                        StoreFiles.Add(CharacterFileName, StoreFile);
                    }

                    //
                    // Enumerate file currently in the file system directory,
                    // transferring each corresponding file from the store
                    // directory if the modified date of the store file is
                    // after the modified date of the local file.
                    //

                    if (Directory.Exists(SyncPath))
                    {
                        FsFiles = Directory.EnumerateFiles(SyncPath);

                        foreach (string FsFileName in FsFiles)
                        {
                            DateTime FsLastModified = File.GetLastWriteTimeUtc(FsFileName);
                            string CharacterFileName = Path.GetFileName(FsFileName);
                            string Key = CharacterFileName.ToLowerInvariant();
                            FileStoreFile StoreFile;
                            string TempFileName = null;

                            if (!StoreFiles.TryGetValue(Key, out StoreFile))
                            {
                                //
                                // This file exists locally but not in the file
                                // store vault.  Keep it (any excess files may be
                                // removed by explicit local vault cleanup).
                                //

                                continue;
                            }

                            //
                            // Transfer the file if the file store vault has a more
                            // recent version.
                            //

                            try
                            {
                                TempFileName = Path.GetTempFileName();

                                try
                                {
                                    using (FileStream FsFile = File.Open(TempFileName, FileMode.Create))
                                    {
                                        StoreFile.ReadIfModifiedSince(FsFile, new DateTimeOffset(FsLastModified));
                                    }

                                    try
                                    {
                                        File.Copy(TempFileName, FsFileName, true);
                                        File.SetLastWriteTimeUtc(FsFileName, StoreFile.LastModified.Value.DateTime);
                                    }
                                    catch
                                    {
                                        //
                                        // Clean up after a failed attempt to
                                        // instantiate copy file.
                                        //

                                        ALFA.SystemInfo.SafeDeleteFile(FsFileName);
                                        throw;
                                    }

                                    if (VerboseLoggingEnabled)
                                    {
                                        Logger.Log("ServerVaultConnector.OnSynchronizeAccountFromVault: Downloaded vault file '{0}\\{1}' with modified date {2} -> {3}.",
                                            AccountName,
                                            CharacterFileName,
                                            FsLastModified,
                                            File.GetLastWriteTimeUtc(FsFileName));
                                    }
                                }
                                catch (FileStoreConditionNotMetException)
                                {
                                    //
                                    // This file was not transferred because it is
                                    // already up to date.
                                    //

                                    Logger.Log("ServerVaultConnector.OnSynchronizeAccountFromVault: Vault file '{0}\\{1}' was already up to date with modified date {2}.",
                                        AccountName,
                                        CharacterFileName,
                                        FsLastModified);
                                }
                            }
                            finally
                            {
                                if (!String.IsNullOrEmpty(TempFileName))
                                    ALFA.SystemInfo.SafeDeleteFile(TempFileName);
                            }

                            //
                            // Remove this file from the list as it has already
                            // been accounted for (it is up to date or has just
                            // been transferred).

                            StoreFiles.Remove(Key);
                        }
                    }

                    //
                    // Sweep any files that were still not yet processed but
                    // existed in the file store vault.  These files are
                    // present on the canonical vault but have not yet been
                    // populated on the local vault, so transfer them now.
                    //

                    foreach (var StoreFile in StoreFiles.Values)
                    {
                        string[] Segments = StoreFile.Uri.Segments;
                        string CharacterFileName = Segments[Segments.Length - 1].ToLowerInvariant();
                        string FsFileName = SyncPath + Path.DirectorySeparatorChar + CharacterFileName;
                        string TempFileName = null;

                        if (!ALFA.SystemInfo.IsSafeFileName(CharacterFileName))
                            throw new ApplicationException("Unsafe filename '" + CharacterFileName + "' on vault for account '" + AccountName + "'.");

                        if (!DirCreated)
                        {
                            DirCreated = Directory.Exists(SyncPath);

                            //
                            // Create the sync directory if it does not exist.
                            // Attempt to preserve case from the vault store if
                            // possible, but fall back to using the case that
                            // the client specified at login time otherwise.
                            //

                            if (!DirCreated)
                            {
                                try
                                {
                                    string OriginalName;

                                    StoreFile.FetchAttributes();

                                    OriginalName = StoreFile.Metadata["OriginalFileName"];

                                    if (OriginalName != null && OriginalName.ToLowerInvariant() == AccountName + "/" + CharacterFileName)
                                    {
                                        OriginalName = OriginalName.Split('/').FirstOrDefault();

                                        DirectoryInfo Parent = Directory.GetParent(SyncPath);

                                        Directory.CreateDirectory(Parent.FullName + "\\" + OriginalName);

                                        if (VerboseLoggingEnabled)
                                        {
                                            Logger.Log("ServerVaultConnector.OnSynchronizeAccountFromVault: Created vault directory for account '{0}'.", OriginalName);
                                        }

                                        DirCreated = true;
                                    }
                                }
                                catch (Exception e)
                                {
                                    Logger.Log("ServerVaultConnector.OnSynchronizeAccountFromVault: Exception {0} recovering canonical case for creating vault directory '{1}', using account name from client instead.",
                                        e,
                                        OriginalAccountName);
                                }

                                if (!DirCreated)
                                {
                                    Directory.CreateDirectory(SyncPath);
                                    DirCreated = true;
                                }
                            }
                        }

                        try
                        {
                            TempFileName = Path.GetTempFileName();

                            using (FileStream FsFile = File.Open(TempFileName, FileMode.OpenOrCreate))
                            {
                                StoreFile.Read(FsFile);
                            }

                            try
                            {
                                File.Copy(TempFileName, FsFileName);
                                File.SetLastWriteTimeUtc(FsFileName, StoreFile.LastModified.Value.DateTime);
                            }
                            catch
                            {
                                //
                                // Clean up after a failed attempt to
                                // instantiate a new file.
                                //

                                ALFA.SystemInfo.SafeDeleteFile(FsFileName);
                                throw;
                            }

                            if (VerboseLoggingEnabled)
                            {
                                Logger.Log("ServerVaultConnector.OnSynchronizeAccountFromVault: Downloaded new vault file '{0}\\{1}' with modified date {2}.",
                                    AccountName,
                                    CharacterFileName,
                                    File.GetLastWriteTimeUtc(FsFileName));
                            }
                        }
                        finally
                        {
                            ALFA.SystemInfo.SafeDeleteFile(TempFileName);
                        }
                    }

                    return 1;
                }
                catch (Exception e)
                {
                    Logger.Log("ServerVaultConnector.OnSynchronizeAccountFromVault('{0}', '{1}'): Exception: {2}",
                        AccountName,
                        SyncPath,
                        e);

                    throw;
                }
            }
            catch
            {
                return 0;
            }
        }