Skip to content

Commit

Permalink
Store SHA for each cfg and log added/changed/removed cfg
Browse files Browse the repository at this point in the history
  • Loading branch information
sarbian committed Jan 10, 2016
1 parent bf4cdfa commit 200fb3e
Showing 1 changed file with 91 additions and 9 deletions.
100 changes: 91 additions & 9 deletions moduleManager.cs
Expand Up @@ -449,7 +449,6 @@ public class MMPatchLoader : LoadingSystem

public static bool keepPartDB = false;


private string activity = "Module Manager";

private static readonly Dictionary<string, Regex> regexCache = new Dictionary<string, Regex>();
Expand All @@ -475,12 +474,12 @@ public class MMPatchLoader : LoadingSystem

private UrlDir.UrlFile physicsUrlFile;

private string configSha;
private Dictionary<string, string> filesSha = new Dictionary<string, string>();

private static string configSha;

private static bool useCache = false;
private bool useCache = false;

private static readonly Stopwatch patchSw = new Stopwatch();
private readonly Stopwatch patchSw = new Stopwatch();

private static readonly List<ModuleManagerPostPatchCallback> postPatchCallbacks =
new List<ModuleManagerPostPatchCallback>();
Expand Down Expand Up @@ -696,7 +695,6 @@ Coroutine StartCoroutine(IEnumerator enumerator, bool blocking)
}
}


private IEnumerator ProcessPatch(bool blocking)
{
try
Expand Down Expand Up @@ -973,22 +971,30 @@ private void IsCacheUpToDate()
sw.Start();

System.Security.Cryptography.SHA256 sha = System.Security.Cryptography.SHA256.Create();
System.Security.Cryptography.SHA256 filesha = System.Security.Cryptography.SHA256.Create();
UrlDir.UrlFile[] files = GameDatabase.Instance.root.AllConfigFiles.ToArray();
for (int i = 0; i < files.Length; i++)
{
// Hash the file path so the checksum change if files are moved
byte[] pathBytes = Encoding.UTF8.GetBytes(files[i].url);
sha.TransformBlock(pathBytes, 0, pathBytes.Length, pathBytes, 0);

// hash the file content
byte[] contentBytes = File.ReadAllBytes(files[i].fullPath);
if (i == files.Length - 1)
sha.TransformFinalBlock(contentBytes, 0, contentBytes.Length);
else
sha.TransformBlock(contentBytes, 0, contentBytes.Length, contentBytes, 0);


filesha.ComputeHash(contentBytes);
filesSha.Add(files[i].url, BitConverter.ToString(filesha.Hash));

}

configSha = BitConverter.ToString(sha.Hash);
sha.Clear();
filesha.Clear();

sw.Stop();

Expand All @@ -1004,7 +1010,9 @@ private void IsCacheUpToDate()
string storedSHA = shaConfigNode.GetValue("SHA");
string version = shaConfigNode.GetValue("version");
string kspVersion = shaConfigNode.GetValue("KSPVersion");
useCache = storedSHA.Equals(configSha);
ConfigNode filesShaNode = shaConfigNode.GetNode("FilesSHA");
useCache = CheckFilesChange(files, filesShaNode);
useCache = useCache && storedSHA.Equals(configSha);
useCache = useCache && version.Equals(Assembly.GetExecutingAssembly().GetName().Version.ToString());
useCache = useCache && kspVersion.Equals(Versioning.version_major + "." + Versioning.version_minor + "." + Versioning.Revision + "." + Versioning.BuildID);
useCache = useCache && File.Exists(cachePath);
Expand All @@ -1016,13 +1024,65 @@ private void IsCacheUpToDate()
}
}

private bool CheckFilesChange(UrlDir.UrlFile[] files, ConfigNode shaConfigNode)
{
bool noChange = true;
StringBuilder changes = new StringBuilder();

for (int i = 0; i < files.Length; i++)
{
ConfigNode fileNode = getFileNode(shaConfigNode, files[i].url);
string fileSha = fileNode != null ? fileNode.GetValue("SHA") : null;

if (fileNode == null)
continue;

if (fileSha == null || filesSha[files[i].url] != fileSha)
{
changes.Append("Changed : " + fileNode.GetValue("filename") + ".cfg\n");
noChange = false;
}
}
for (int i = 0; i < files.Length; i++)
{
ConfigNode fileNode = getFileNode(shaConfigNode, files[i].url);

if (fileNode == null)
{
changes.Append("Added : " + files[i].url + ".cfg\n");
noChange = false;
}
shaConfigNode.RemoveNode(fileNode);
}
foreach (ConfigNode fileNode in shaConfigNode.GetNodes())
{
changes.Append("Deleted : " + fileNode.GetValue("filename") + ".cfg\n");
noChange = false;
}
if (!noChange)
log("Changes :\n" + changes.ToString());
return noChange;
}

private ConfigNode getFileNode(ConfigNode shaConfigNode, string filename)
{
for (int i = 0; i < shaConfigNode.nodes.Count; i++)
{
ConfigNode file = shaConfigNode.nodes[i];
if (file.name == "FILE" && file.GetValue("filename") == filename)
return file;
}
return null;
}


private void CreateCache()
{
ConfigNode shaConfigNode = new ConfigNode();
shaConfigNode.AddValue("SHA", configSha);
shaConfigNode.AddValue("version", Assembly.GetExecutingAssembly().GetName().Version.ToString());
shaConfigNode.AddValue("KSPVersion", Versioning.version_major + "." + Versioning.version_minor + "." + Versioning.Revision + "." + Versioning.BuildID);
shaConfigNode.Save(shaPath);
ConfigNode filesSHANode = shaConfigNode.AddNode("FilesSHA");

ConfigNode cache = new ConfigNode();

Expand All @@ -1040,6 +1100,28 @@ private void CreateCache()
node.AddNode(config.config);
}

foreach (var file in GameDatabase.Instance.root.AllConfigFiles)
{
// "/Physics" is the node we created manually to loads the PHYSIC config
if (file.url != "/Physics" && filesSha.ContainsKey(file.url))
{
ConfigNode shaNode = filesSHANode.AddNode("FILE");
shaNode.AddValue("filename", file.url);
shaNode.AddValue("SHA", filesSha[file.url]);
filesSha.Remove(file.url);
}
}

log("Saving cache");

try
{
shaConfigNode.Save(shaPath);
}
catch (Exception e)
{
log("Exception while saving the sha\n" + e.ToString());
}
try
{
cache.Save(cachePath);
Expand Down

0 comments on commit 200fb3e

Please sign in to comment.