Skip to content

Commit

Permalink
added ability to detect clashes between mods
Browse files Browse the repository at this point in the history
works fine I hope...
  • Loading branch information
monkeyman192 committed Dec 1, 2017
1 parent afea370 commit 35378b7
Show file tree
Hide file tree
Showing 2 changed files with 160 additions and 16 deletions.
41 changes: 39 additions & 2 deletions PSArcTool/Functions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,43 @@ public static void Extract(string pakFilePath)
}
}

public static List<string> ListContents(string pakFilePath)
{
var path = Path.GetTempFileName() + ".exe"; // Actually PSARC.EXE, but we just call it something random just cause.
File.WriteAllBytes(path, Properties.Resources.psarc);
var pakFile = new FileInfo(pakFilePath);

List<string> pakContents = new List<string>();

if (pakFile.Exists)
{
var psarcArgs = string.Format("list \"{0}\"", pakFile.FullName);
var proc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = path,
Arguments = psarcArgs,
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
proc.Start();
while (!proc.StandardOutput.EndOfStream)
{
string line = proc.StandardOutput.ReadLine();
if (!line.StartsWith("Listing"))
{
if (line.StartsWith("/"))
line = line.Substring(1);
pakContents.Add(line.Split(' ')[0]);
}
}
}
return pakContents;
}

public static void Create(string dirPath)
{
if (Directory.Exists(dirPath))
Expand All @@ -40,7 +77,7 @@ public static void Create(string dirPath)
}
}

public static void Create(IList<string> paths, string rootPath = null)
public static void Create(IList<string> paths, string rootPath = null, string fname = "psarc.pak")
{
if (paths.Any() && paths.All(path => File.Exists(path) || Directory.Exists(path)))
{
Expand Down Expand Up @@ -86,7 +123,7 @@ public static void Create(IList<string> paths, string rootPath = null)
}
}
Run(
string.Format("create -a --zlib --inputfile=\"{0}\" --output={1}", tmpFilePath, "psarc.pak"),
string.Format("create -a --zlib --inputfile=\"{0}\" --output={1}", tmpFilePath, fname),
rootPath);
}
}
Expand Down
135 changes: 121 additions & 14 deletions PSArcTool/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Threading;

namespace PSArcTool
{
Expand All @@ -19,10 +21,39 @@ static void Main(string[] args)
Console.WriteLine("PSArcTool");
Console.WriteLine("Periander 2016-08-17");
Console.WriteLine("I was mucking around with No Man's Sky modding and wanted to make extracting/creating PAK files easier.");
foreach (var arg in args)
Console.WriteLine("Modified by monkeyman192 to allow for mod conflict checking (use the arg -list for a simple list, and -listall for a detailed breakdown of clashes)");

// let's go through the arguments and see if we have any kwargs
// possibilities:
// out=fname - this is the name of the output pak file
// -list - this will return a list of all files in the pak file
string fname = "";
bool returnlist = false;
string returnlistmode = "concise";
foreach (string arg in args)
{
Console.WriteLine(arg);
if (arg.Contains("out="))
{
fname = String.Format("{0}.pak", arg.Substring(4));
args = args.Where(val => val != arg).ToArray();
}
else
fname = "psarc.pak";
if (arg == "-list" || arg == "-listall")
{
returnlist = true;
if (arg == "-list")
returnlistmode = "concise";
if (arg == "-listall")
returnlistmode = "verbose";
args = args.Where(val => val != arg).ToArray();
}
}
//Console.WriteLine(String.Format("output name: {0}", fname));
/*foreach (var arg in args)
{
Console.WriteLine(arg);
}*/


//// TESTING
Expand All @@ -38,24 +69,100 @@ static void Main(string[] args)

//};

if (args.Any() &&
args.All(arg => File.Exists(arg) && (arg.EndsWith(".pak", StringComparison.OrdinalIgnoreCase) || arg.EndsWith(".psarc", StringComparison.OrdinalIgnoreCase))))
if (returnlist)
{
foreach (var pakFilePath in args)
// check to see if all the arguments are files ending with .pak, or the arguments specified are folders
if (args.Any() &&
(args.All(arg => File.Exists(arg) && (arg.EndsWith(".pak", StringComparison.OrdinalIgnoreCase) || arg.EndsWith(".psarc", StringComparison.OrdinalIgnoreCase))) ||
args.All(arg => Directory.Exists(arg))))
{
Functions.Extract(pakFilePath);
// let's get all the sub-directory paks:
List<string> extraMods = new List<string>();
foreach (string dir in args.Where(dir => Directory.Exists(dir)))
{
IEnumerable<string> files = Directory.EnumerateFiles(dir, "*.pak", SearchOption.AllDirectories);
extraMods.AddRange(files);
}
// and then add them to the args list
extraMods.AddRange(args);
args = extraMods.ToArray<string>();

// List of kvp's, with the key being the name of the pak, and the value being a list of all contained files
Dictionary<string, List<string>> containedFiles = new Dictionary<string, List<string>>();
// Dictionary with the key being the name of the
Dictionary<string, List<string>> sharedFiles = new Dictionary<string, List<string>>();
foreach (var pakFilePath in args)
{
// get the contents of the pak
List<string> pakContents = Functions.ListContents(pakFilePath);
// next, iterate over the current contents of the contained files dict
foreach (KeyValuePair<string, List<string>> kvp in containedFiles)
{
// for each pak file, create an enumerable with the list of shared files
IEnumerable<string> intersection = kvp.Value.Intersect(pakContents);
// and for each file that is shared, add the information to the sharedFiles dictionary
foreach (string file in intersection)
{
// if the file that is shared is already a key in the shared file dictionary, then simply add the new name to the list for the key
if (sharedFiles.ContainsKey(file))
sharedFiles[file].Add(pakFilePath);
// otherwise add a new list with the names of both pak's
else
sharedFiles.Add(file, new List<string> { kvp.Key, pakFilePath });
}
}
containedFiles.Add(pakFilePath, Functions.ListContents(pakFilePath));
}

if (sharedFiles.Count() != 0)
{
Console.WriteLine("\nThe following mods clash:");
if (returnlistmode == "concise")
{
IEnumerable<string> clashingMods = Enumerable.Empty<string>();
foreach (KeyValuePair<string, List<string>> kvp in sharedFiles)
clashingMods = clashingMods.Union(kvp.Value);
foreach (string mod in clashingMods)
Console.WriteLine(mod);
}
// in this case, write all the files that clash in each mod (they asked for it!!)
else if (returnlistmode == "verbose")
{
foreach (KeyValuePair<string, List<string>> kvp in sharedFiles)
{
foreach (string mod in kvp.Value)
{
Console.WriteLine("{0} is in the file {1}", kvp.Key, mod);
}
}
}
}
else
Console.WriteLine("\nNo mods clash!");

Console.WriteLine("\nPress ENTER to quit.");
Console.ReadLine();
}
}
else if (args.Any() && args.All(arg => File.Exists(arg) || Directory.Exists(arg)))
// A collection of files or folders
{
Functions.Create(args, string.Empty);
}
else
{
waitForEnter = true;
Console.WriteLine(
"Usage: Pass PAK/PSARC files as arguments to extract (click and drag on to PSArcTool). Pass anything else to create a PAK file.");
if (args.Any() &&
args.All(arg => File.Exists(arg) && (arg.EndsWith(".pak", StringComparison.OrdinalIgnoreCase) || arg.EndsWith(".psarc", StringComparison.OrdinalIgnoreCase))))
{
foreach (var pakFilePath in args)
Functions.Extract(pakFilePath);

}
else if (args.Any() && args.All(arg => File.Exists(arg) || Directory.Exists(arg)))
// A collection of files or folders
{
Functions.Create(args, string.Empty, fname);
}
else
{
waitForEnter = true;
Console.WriteLine("Usage: Pass PAK/PSARC files as arguments to extract (click and drag on to PSArcTool). Pass anything else to create a PAK file.");
}
}

}
Expand Down

0 comments on commit 35378b7

Please sign in to comment.