Skip to content

Instantly share code, notes, and snippets.

@Quit
Created August 6, 2016 10:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Quit/c6d84267376157837507801481a7df3a to your computer and use it in GitHub Desktop.
Save Quit/c6d84267376157837507801481a7df3a to your computer and use it in GitHub Desktop.
Extracts Stonehearth .smods in a semi-efficient way, auto-commits to git if configured
using System;
using System.Linq;
using System.Threading.Tasks;
using System.IO;
using System.Diagnostics;
namespace RP.Unwrp2016
{
class Program
{
private static string CommitMessage;
static void Main(string[] args)
{
// Get the game version so we can properly do commit messages
var version = FileVersionInfo.GetVersionInfo(new FileInfo(Path.Combine(Environment.CurrentDirectory, "..", "Stonehearth.exe")).FullName);
CommitMessage = $"Updated to {version.ProductVersion}.{version.ProductPrivatePart} ({version.FileVersion})";
// Get all .smods within our cwd
var smods = Directory.GetFiles(Environment.CurrentDirectory, "*.smod");
// Because we can't get 7z to use threading, we'll make the best of it
Parallel.ForEach(smods, ExtractSmod);
// Don't forget some radio calisthenics
Console.WriteLine();
Console.WriteLine(@"\o/ VICTORY! \o/");
}
private static void ExtractSmod(string smodPath)
{
var smodName = Path.GetFileNameWithoutExtension(smodPath);
var tmpDir = new DirectoryInfo(Path.Combine(Path.GetTempPath(), $"rpu{smodName}"));
if (tmpDir.Exists)
tmpDir.Delete(true);
tmpDir.Create();
// Launch the extraction
var p = Process.Start(new ProcessStartInfo
{
FileName = Properties.Settings.Default.SevenZipPath,
Arguments = $"x \"{smodPath}\" -o\"{tmpDir.FullName}\" *",
UseShellExecute = false
});
p.WaitForExit();
if (p.ExitCode != 0)
{
Console.Error.WriteLine("Could not extract {0}!", smodPath);
Console.ReadLine();
Environment.Exit(1);
}
// Does the folder not exist?
var inDir = tmpDir.GetDirectories(smodName).Single();
var outDir = new DirectoryInfo(Path.Combine(Environment.CurrentDirectory, smodName));
if (!outDir.Exists)
{
inDir.MoveTo(outDir.FullName);
return;
}
var inFiles = inDir.GetFiles("*", SearchOption.AllDirectories).Select(f => f.FullName.Substring(inDir.FullName.Length+1)).ToList();
var outFiles = outDir.GetFiles("*", SearchOption.AllDirectories).Where(f => !f.DirectoryName.Contains(".git")).Select(f => f.FullName.Substring(outDir.FullName.Length+1)).ToList();
// Delete all obsolete files
foreach (var deletee in outFiles.Except(inFiles))
{
File.Delete(Path.Combine(outDir.FullName, deletee));
}
// Move all files from the temp folder out
Parallel.ForEach(inFiles, file =>
{
var outFile = new FileInfo(Path.Combine(outDir.FullName, file));
if (outFile.Exists)
outFile.Delete();
File.Move(Path.Combine(inDir.FullName, file), outFile.FullName);
});
// Delete the temp folder - it should be empty by now anyway.
tmpDir.Delete(true);
// Is it something git-y? If so, commit
if (Directory.Exists(Path.Combine(outDir.FullName, ".git")))
{
CallGit(outDir.FullName, "add -A");
CallGit(outDir.FullName, $"commit -m \"{CommitMessage}\"");
}
// Rename the .smod
File.Move(smodPath, smodPath + DateTime.Now.ToString("yyyyMMddHHmmss"));
}
private static void CallGit(string workingDirectory, string arguments)
{
Process.Start(new ProcessStartInfo
{
FileName = Properties.Settings.Default.GitPath,
Arguments = arguments,
WorkingDirectory = workingDirectory,
UseShellExecute = false
})
.WaitForExit();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment