<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="1">
<Button Width="100" Height="23" Margin="2" Content="Query files" Command="{Binding PlayerDataStorageQueryFileList}" />
<Button Width="100" Height="23" Margin="2" Content="Upload file" Command="{Binding PlayerDataStorageWriteFile}" />
<StackPanel Orientation="Horizontal">
<Button Width="100" Height="23" Margin="2" Content="Download file" Command="{Binding PlayerDataStorageReadFile}" />
<Button Width="100" Height="23" Margin="2" Content="Duplicate file" Command="{Binding PlayerDataStorageDuplicateFile}" />
</StackPanel>
<Button Width="100" Height="23" Margin="2" Content="Delete file" Command="{Binding PlayerDataStorageDeleteFile}" />
</StackPanel>
<ListView x:Name="PlayerDataStorageFilesListView" Grid.Column="0" Margin="2" ItemsSource="{Binding PlayerDataStorageFiles}" SelectedItem="{Binding SelectedPlayerDataStorageFile}" SelectionChanged="PlayerDataStorageFilesListView_SelectionChanged">
<ListView.View>
<GridView>
<GridViewColumn Header="Filename" Width="150" DisplayMemberBinding="{Binding Filename}">
<GridViewColumn.HeaderContainerStyle>
<Style TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="HorizontalContentAlignment" Value="Left" />
</Style>
</GridViewColumn.HeaderContainerStyle>
</GridViewColumn>
<GridViewColumn Header="LastModifiedTime" Width="175" DisplayMemberBinding="{Binding LastModifiedTime}">
<GridViewColumn.HeaderContainerStyle>
<Style TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="HorizontalContentAlignment" Value="Left" />
</Style>
</GridViewColumn.HeaderContainerStyle>
</GridViewColumn>
<GridViewColumn Header="FileSizeBytes" Width="75" DisplayMemberBinding="{Binding FileSizeBytes}">
<GridViewColumn.HeaderContainerStyle>
<Style TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="HorizontalContentAlignment" Value="Left" />
</Style>
</GridViewColumn.HeaderContainerStyle>
</GridViewColumn>
<GridViewColumn Header="UnencryptedDataSizeBytes" Width="150" DisplayMemberBinding="{Binding UnencryptedDataSizeBytes}">
<GridViewColumn.HeaderContainerStyle>
<Style TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="HorizontalContentAlignment" Value="Left" />
</Style>
</GridViewColumn.HeaderContainerStyle>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
public partial class PlayerDataStorageView :UserControl
{
public PlayerDataStorageViewModel ViewModel { get { return ViewModelLocator.PlayerDataStorage; } }
public PlayerDataStorageView()
{
InitializeComponent();
DataContext = ViewModel;
}
private void PlayerDataStorageFilesListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
}
}
public class PlayerDataStorageViewModel :BindableBase
{
private ObservableCollection<FileMetadata> _playerDataStorageFiles;
public ObservableCollection<FileMetadata> PlayerDataStorageFiles
{
get { return _playerDataStorageFiles; }
set { SetProperty(ref _playerDataStorageFiles, value); }
}
private FileMetadata _selectedPlayerDataStorageFile;
public FileMetadata SelectedPlayerDataStorageFile
{
get { return _selectedPlayerDataStorageFile; }
set { SetProperty(ref _selectedPlayerDataStorageFile, value); }
}
}
private static PlayerDataStorageViewModel _playerDataStorage;
public static PlayerDataStorageViewModel PlayerDataStorage
{
get { return _playerDataStorage ??= new PlayerDataStorageViewModel(); }
}
public static class PlayerDataStorageService
{
public static void QueryFileList()
{
var queryFileListOptions = new QueryFileListOptions()
{
LocalUserId = ProductUserId.FromString(ViewModelLocator.Main.ProductUserId)
};
ViewModelLocator.Main.StatusBarText = "Querying player data storage file list...";
App.Settings.PlatformInterface.GetPlayerDataStorageInterface()
.QueryFileList(queryFileListOptions, null, (QueryFileListCallbackInfo queryFileListCallbackInfo) =>
{
Debug.WriteLine($"QueryFileList {queryFileListCallbackInfo.ResultCode}");
if (queryFileListCallbackInfo.ResultCode == Result.Success)
{
for (uint i = 0; i < queryFileListCallbackInfo.FileCount; i++)
{
var copyFileMetadataAtIndexOptions = new CopyFileMetadataAtIndexOptions()
{
Index = i,
LocalUserId = ProductUserId.FromString(ViewModelLocator.Main.ProductUserId)
};
var result = App.Settings.PlatformInterface.GetPlayerDataStorageInterface()
.CopyFileMetadataAtIndex(copyFileMetadataAtIndexOptions, out var metadata);
if (result == Result.Success)
{
ViewModelLocator.PlayerDataStorage.PlayerDataStorageFiles
.Add(metadata);
}
}
}
ViewModelLocator.Main.StatusBarText = string.Empty;
});
}
}
public class PlayerDataStorageQueryFileListCommand :CommandBase
{
public override bool CanExecute(object parameter)
{
return !string.IsNullOrWhiteSpace(ViewModelLocator.Main.ProductUserId);
}
public override void Execute(object parameter)
{
ViewModelLocator.PlayerDataStorage.PlayerDataStorageFiles = new ObservableCollection<FileMetadata>();
PlayerDataStorageService.QueryFileList();
}
}
public PlayerDataStorageQueryFileListCommand PlayerDataStorageQueryFileList { get; set; }
public PlayerDataStorageViewModel()
{
PlayerDataStorageQueryFileList = new PlayerDataStorageQueryFileListCommand();
}
PlayerDataStorage.PlayerDataStorageQueryFileList.RaiseCanExecuteChanged();
<TabItem x:Name="PlayerDataStorage" Header="Player Data Storage">
<views:PlayerDataStorageView />
</TabItem>
[Warning] LogEOSPlayerDataStorage - Querying file failed, got 0 results.
QueryFileList NotFound
public static void WriteFile(OpenFileDialog openFileDialog)
{
var bytesWritten = 0;
var writeFileOptions = new WriteFileOptions()
{
LocalUserId = ProductUserId.FromString(ViewModelLocator.Main.ProductUserId),
Filename = openFileDialog.SafeFileName,
ChunkLengthBytes = 10485760,
WriteFileDataCallback = (WriteFileDataCallbackInfo writeFileDataCallbackInfo, out byte[] buffer) =>
{
using var fs = new FileStream($"{openFileDialog.FileName}", FileMode.Open, FileAccess.Read);
if (fs.Length > bytesWritten)
{
var readBytes = new byte[System.Math.Min(writeFileDataCallbackInfo.DataBufferLengthBytes, fs.Length)];
fs.Seek(bytesWritten, SeekOrigin.Begin);
bytesWritten += fs.Read(readBytes, 0, (int)System.Math.Min(writeFileDataCallbackInfo
.DataBufferLengthBytes, fs.Length));
buffer = readBytes;
}
else
{
buffer = new byte[0];
return WriteResult.CompleteRequest;
}
return WriteResult.ContinueWriting;
},
FileTransferProgressCallback = (FileTransferProgressCallbackInfo fileTransferProgressCallbackInfo) =>
{
var percentComplete = (double)fileTransferProgressCallbackInfo.BytesTransferred / (double)fileTransferProgressCallbackInfo.TotalFileSizeBytes * 100;
ViewModelLocator.Main.StatusBarText = $"Downloading file <{fileTransferProgressCallbackInfo.Filename}> ({System.Math.Ceiling(percentComplete)}%)...";
}
};
ViewModelLocator.Main.StatusBarText = $"Uploading file <{writeFileOptions.Filename}> (creating buffer)...";
var fileTransferRequest = App.Settings.PlatformInterface
.GetPlayerDataStorageInterface().WriteFile(writeFileOptions, null, (WriteFileCallbackInfo writeFileCallbackInfo) =>
{
Debug.WriteLine($"WriteFile {writeFileCallbackInfo.ResultCode}");
if (writeFileCallbackInfo.ResultCode == Result.Success)
{
ViewModelLocator.PlayerDataStorage
.PlayerDataStorageQueryFileList.Execute(null);
Debug.WriteLine($"Successfully uploaded {writeFileCallbackInfo.Filename}.");
ViewModelLocator.Main.StatusBarText = string.Empty;
}
else
{
Debug.WriteLine($"Error uploading {writeFileCallbackInfo.Filename}:{writeFileCallbackInfo.ResultCode}.");
ViewModelLocator.Main.StatusBarText = string.Empty;
}
});
if (fileTransferRequest == null)
{
Debug.WriteLine("Error uploading file:bad handle");
ViewModelLocator.Main.StatusBarText = string.Empty;
}
}
public class PlayerDataStorageWriteFileCommand :CommandBase
{
public override bool CanExecute(object parameter)
{
return !string.IsNullOrWhiteSpace(ViewModelLocator.Main.ProductUserId);
}
public override void Execute(object parameter)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
if (openFileDialog.ShowDialog() == true)
{
PlayerDataStorageService.WriteFile(openFileDialog);
}
}
}
public PlayerDataStorageQueryFileListCommand PlayerDataStorageQueryFileList { get; set; }
public PlayerDataStorageWriteFileCommand PlayerDataStorageWriteFile { get; set; }
public PlayerDataStorageViewModel()
{
PlayerDataStorageQueryFileList = new PlayerDataStorageQueryFileListCommand();
PlayerDataStorageWriteFile = new PlayerDataStorageWriteFileCommand();
}
PlayerDataStorage.PlayerDataStorageWriteFile.RaiseCanExecuteChanged();
public static void ReadFile(FileMetadata fileMetadata)
{
var readFileOptions = new ReadFileOptions()
{
LocalUserId = ProductUserId.FromString(ViewModelLocator.Main.ProductUserId),
Filename = fileMetadata.Filename,
ReadChunkLengthBytes = 1048576,
ReadFileDataCallback = (ReadFileDataCallbackInfo readFileDataCallbackInfo) =>
{
using var fs = new FileStream($"{App.Settings.CacheDirectory}{readFileDataCallbackInfo.Filename}", FileMode.Append, FileAccess.Write);
fs.Write(readFileDataCallbackInfo.DataChunk, 0, readFileDataCallbackInfo.DataChunk.Length);
return ReadResult.ContinueReading;
},
FileTransferProgressCallback = (FileTransferProgressCallbackInfo fileTransferProgressCallbackInfo) =>
{
var percentComplete = (double)fileTransferProgressCallbackInfo.BytesTransferred / (double)fileTransferProgressCallbackInfo.TotalFileSizeBytes * 100;
ViewModelLocator.Main.StatusBarText = $"Downloading file <{fileTransferProgressCallbackInfo.Filename}> ({System.Math.Ceiling(percentComplete)}%)...";
}
};
ViewModelLocator.Main.StatusBarText = $"Downloading file <{readFileOptions.Filename}> (creating buffer)...";
var fileTransferRequest = App.Settings.PlatformInterface
.GetPlayerDataStorageInterface().ReadFile(readFileOptions, null, (ReadFileCallbackInfo readFileCallbackInfo) =>
{
Debug.WriteLine($"ReadFile {readFileCallbackInfo.ResultCode}");
if (readFileCallbackInfo.ResultCode == Result.Success)
{
Debug.WriteLine($"Successfully downloaded {readFileCallbackInfo.Filename} to {App.Settings.CacheDirectory}.");
ViewModelLocator.Main.StatusBarText = string.Empty;
}
});
if (fileTransferRequest == null)
{
Debug.WriteLine("Error downloading file:bad handle");
ViewModelLocator.Main.StatusBarText = string.Empty;
}
}
public class PlayerDataStorageReadFileCommand :CommandBase
{
public override bool CanExecute(object parameter)
{
return ViewModelLocator.PlayerDataStorage.SelectedPlayerDataStorageFile != null;
}
public override void Execute(object parameter)
{
PlayerDataStorageService.ReadFile(ViewModelLocator
.PlayerDataStorage.SelectedPlayerDataStorageFile);
}
}
public PlayerDataStorageQueryFileListCommand PlayerDataStorageQueryFileList { get; set; }
public PlayerDataStorageWriteFileCommand PlayerDataStorageWriteFile { get; set; }
public PlayerDataStorageReadFileCommand PlayerDataStorageReadFile { get; set; }
public PlayerDataStorageViewModel()
{
PlayerDataStorageQueryFileList = new PlayerDataStorageQueryFileListCommand();
PlayerDataStorageWriteFile = new PlayerDataStorageWriteFileCommand();
PlayerDataStorageReadFile = new PlayerDataStorageReadFileCommand();
}
ViewModel.PlayerDataStorageReadFile.RaiseCanExecuteChanged();
ReadFile Success
Successfully downloaded test_file.txt to C:\Users\<User>\AppData\Local\Temp\.
public static void DuplicateFile(FileMetadata fileMetadata)
{
var duplicateFileOptions = new DuplicateFileOptions()
{
LocalUserId = ProductUserId.FromString(ViewModelLocator.Main.ProductUserId),
SourceFilename = fileMetadata.Filename,
DestinationFilename = $"{fileMetadata.Filename}_(copy)"
};
ViewModelLocator.Main.StatusBarText = $"Copying <{duplicateFileOptions.SourceFilename}> as <{duplicateFileOptions.DestinationFilename}>...";
App.Settings.PlatformInterface.GetPlayerDataStorageInterface()
.DuplicateFile(duplicateFileOptions, null, (DuplicateFileCallbackInfo duplicateFileCallbackInfo) =>
{
Debug.WriteLine($"DuplicateFile {duplicateFileCallbackInfo.ResultCode}");
if (duplicateFileCallbackInfo.ResultCode == Result.Success)
{
ViewModelLocator.PlayerDataStorage
.PlayerDataStorageQueryFileList.Execute(null);
ViewModelLocator.Main.StatusBarText = "Successfully copied file.";
}
else
{
Debug.WriteLine("Copying file failed:" + duplicateFileCallbackInfo.ResultCode);
ViewModelLocator.Main.StatusBarText = string.Empty;
}
});
}
public class PlayerDataStorageDuplicateFileCommand :CommandBase
{
public override bool CanExecute(object parameter)
{
return ViewModelLocator.PlayerDataStorage.SelectedPlayerDataStorageFile != null;
}
public override void Execute(object parameter)
{
PlayerDataStorageService.DuplicateFile(ViewModelLocator
.PlayerDataStorage.SelectedPlayerDataStorageFile);
}
}
public PlayerDataStorageQueryFileListCommand PlayerDataStorageQueryFileList { get; set; }
public PlayerDataStorageWriteFileCommand PlayerDataStorageWriteFile { get; set; }
public PlayerDataStorageReadFileCommand PlayerDataStorageReadFile { get; set; }
public PlayerDataStorageDuplicateFileCommand PlayerDataStorageDuplicateFile { get; set; }
public PlayerDataStorageViewModel()
{
PlayerDataStorageQueryFileList = new PlayerDataStorageQueryFileListCommand();
PlayerDataStorageWriteFile = new PlayerDataStorageWriteFileCommand();
PlayerDataStorageReadFile = new PlayerDataStorageReadFileCommand();
PlayerDataStorageDuplicateFile = new PlayerDataStorageDuplicateFileCommand();
}
ViewModel.PlayerDataStorageDuplicateFile.RaiseCanExecuteChanged();
public static void DeleteFile(FileMetadata fileMetadata)
{
var deleteFileOptions = new DeleteFileOptions()
{
LocalUserId = ProductUserId.FromString(ViewModelLocator.Main.ProductUserId),
Filename = fileMetadata.Filename
};
ViewModelLocator.Main.StatusBarText = $"Deleting <{deleteFileOptions.Filename}>...";
App.Settings.PlatformInterface.GetPlayerDataStorageInterface()
.DeleteFile(deleteFileOptions, null, (DeleteFileCallbackInfo deleteFileCallbackInfo) =>
{
Debug.WriteLine($"DeleteFile {deleteFileCallbackInfo.ResultCode}");
if (deleteFileCallbackInfo.ResultCode == Result.Success)
{
ViewModelLocator.PlayerDataStorage
.PlayerDataStorageQueryFileList.Execute(null);
ViewModelLocator.Main.StatusBarText = "Successfully deleted file.";
}
else
{
Debug.WriteLine("Deleting file failed:" + deleteFileCallbackInfo.ResultCode);
ViewModelLocator.Main.StatusBarText = string.Empty;
}
});
}
public class PlayerDataStorageDeleteFileCommand :CommandBase
{
public override bool CanExecute(object parameter)
{
return ViewModelLocator.PlayerDataStorage.SelectedPlayerDataStorageFile != null;
}
public override void Execute(object parameter)
{
PlayerDataStorageService.DeleteFile(ViewModelLocator
.PlayerDataStorage.SelectedPlayerDataStorageFile);
}
}
public PlayerDataStorageQueryFileListCommand PlayerDataStorageQueryFileList { get; set; }
public PlayerDataStorageWriteFileCommand PlayerDataStorageWriteFile { get; set; }
public PlayerDataStorageReadFileCommand PlayerDataStorageReadFile { get; set; }
public PlayerDataStorageDuplicateFileCommand PlayerDataStorageDuplicateFile { get; set; }
public PlayerDataStorageDeleteFileCommand PlayerDataStorageDeleteFile { get; set; }
public PlayerDataStorageViewModel()
{
PlayerDataStorageQueryFileList = new PlayerDataStorageQueryFileListCommand();
PlayerDataStorageWriteFile = new PlayerDataStorageWriteFileCommand();
PlayerDataStorageReadFile = new PlayerDataStorageReadFileCommand();
PlayerDataStorageDuplicateFile = new PlayerDataStorageDuplicateFileCommand();
PlayerDataStorageDeleteFile = new PlayerDataStorageDeleteFileCommand();
}
ViewModel.PlayerDataStorageDeleteFile.RaiseCanExecuteChanged();