Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added '.NET Transactional File Manager' support, removed our implementation #166

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion CKAN/CKAN/CKAN.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="ChinhDo.Transactions">
<HintPath>..\packages\TxFileManager.1.3\lib\net20\ChinhDo.Transactions.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="CommandLine">
Expand All @@ -45,6 +48,7 @@
<Reference Include="log4net">
<HintPath>..\packages\log4net.2.0.3\lib\net40-full\log4net.dll</HintPath>
</Reference>
<Reference Include="System.Transactions" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
Expand Down Expand Up @@ -75,5 +79,4 @@
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup />
</Project>
7 changes: 7 additions & 0 deletions CKAN/CKAN/KSPManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ internal static KSP _GetPreferredInstance()
// Return the autostart, if we can find it.
if (AutoStartInstance != null)
{
// We check both null and "" as we can't write NULL to the registry, so we write an empty string instead
// This is neccessary so we can indicate that the user wants to reset the current AutoStartInstance without clearing the windows registry keys!
if (AutoStartInstance == "")
{
return null;
}

if (Instances.ContainsKey(AutoStartInstance))
{
return Instances[AutoStartInstance];
Expand Down
53 changes: 48 additions & 5 deletions CKAN/CKAN/ModuleInstaller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ public static string CachePath(string file)
public void InstallList(List<string> modules, RelationshipResolverOptions options, bool downloadOnly = false)
{
installCanceled = false; // Can be set by another thread
currentTransaction = new FilesystemTransaction(KSPManager.CurrentInstance.TempDir());
currentTransaction = new FilesystemTransaction();

if (onReportProgress != null)
{
Expand Down Expand Up @@ -357,9 +357,16 @@ public List<string> GetModuleContentsList(CkanModule module)

var contents = new List<InstallableFile> ();

foreach (ModuleInstallDescriptor stanza in module.install)
if (module.install != null)
{
contents.AddRange( FindInstallableFiles(stanza, zipfile) );
foreach (ModuleInstallDescriptor stanza in module.install)
{
contents.AddRange(FindInstallableFiles(stanza, zipfile));
}
}
else
{
contents.AddRange(FindAllFiles(zipfile));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uh oh, we already have a method for doing this. GenerateDefaultInstall(). It's not the same as all the files in the archive; instead, we look for the top-most directory that has the same name as the module identifier, and install that.

This is really my fault for not factoring out all the code into something which lets you supply a module and a zipfile, and get back the files which would be installed. (That was kinda what FindInstallableFiles() was meant to do, but it existed before we had default installs).

I'll be sending you a PR on your PR, but it should be a pretty straightforward one. :)

  • Add FindInstallableFiles(Module, Zipfile) or analogue thereof.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a terrible person, I didn't write something that gives back all the installable files from a Module and its Zipfile. I did patch it so it doesn't need FindAllFiles, and does match what would be installed. I also added a TODO. :)

}

var pretty_filenames = new List<string> ();
Expand Down Expand Up @@ -653,6 +660,43 @@ internal List<InstallableFile> FindInstallableFiles(InstallableDescriptor stanza
return files;
}

internal List<InstallableFile> FindAllFiles(ZipFile zipfile)
{
string installDir;
bool makeDirs;
var files = new List<InstallableFile>();

foreach (ZipEntry entry in zipfile)
{
// SKIP the file if it's a .CKAN file, these should never be copied to GameData.
if (Regex.IsMatch(entry.Name, ".CKAN", RegexOptions.IgnoreCase))
{
continue;
}

// Get the full name of the file.
string outputName = entry.Name;

// Strip off everything up to GameData/Ships
// TODO: There's got to be a nicer way of doing path resolution.
outputName = Regex.Replace(outputName, @"^/?(.*(GameData|Ships)/)?", "", RegexOptions.IgnoreCase);

string full_path = Path.Combine("GameData", outputName);

// Make the path pretty, and of course the prettiest paths use Unix separators. ;)
full_path = full_path.Replace('\\', '/');

InstallableFile file_info = new InstallableFile();
file_info.source = entry;
file_info.destination = full_path;
file_info.makedir = false;

files.Add(file_info);
}

return files;
}

private void CopyZipEntry(ZipFile zipfile, ZipEntry entry, string fullPath, bool makeDirs)
{
if (entry.IsDirectory)
Expand Down Expand Up @@ -682,8 +726,7 @@ private void CopyZipEntry(ZipFile zipfile, ZipEntry entry, string fullPath, bool
// It's a file! Prepare the streams
Stream zipStream = zipfile.GetInputStream(entry);

TransactionalFileWriter file = currentTransaction.OpenFileWrite(fullPath);
FileStream output = file.Stream;
FileStream output = currentTransaction.OpenFileWrite(fullPath);

// Copy
zipStream.CopyTo(output);
Expand Down
8 changes: 4 additions & 4 deletions CKAN/CKAN/NetAsyncDownloader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public struct NetAsyncDownloaderDownloadPart
public long bytesLeft;
public int bytesPerSecond;
public Exception error;
public TransactionalFileWriter fileWriter;
public FileStream fileStream;
public int lastProgressUpdateSize;
public DateTime lastProgressUpdateTime;
public string path;
Expand Down Expand Up @@ -57,7 +57,7 @@ public NetAsyncDownloader(Uri[] urls, string[] filenames = null)
public string[] StartDownload()
{
var filePaths = new string[downloads.Length];
transaction = new FilesystemTransaction(KSPManager.CurrentInstance.TempDir());
transaction = new FilesystemTransaction();

for (int i = 0; i < downloads.Length; i++)
{
Expand Down Expand Up @@ -87,8 +87,8 @@ public string[] StartDownload()

downloads[i].agent.DownloadFileCompleted += (sender, args) => FileDownloadComplete(index, args.Error);

downloads[i].fileWriter = transaction.OpenFileWrite(downloads[i].path, false);
downloads[i].agent.DownloadFileAsync(downloads[i].url, downloads[i].fileWriter.TemporaryPath);
transaction.Snapshot(downloads[i].path);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, is this snap-shotting the location that we're going to download to? (Presumably so we can remove a failed download if something goes wrong?)

downloads[i].agent.DownloadFileAsync(downloads[i].url, downloads[i].path);
}

return filePaths;
Expand Down
Loading