blizzless-diiis/src/DiIiS-NA/Core/MPQ/MPQPatchChain.cs
Lucca Faria Ferri 2ebdff6c61 MonsterBrain.cs cleanup.
Removed Blizzless using comments as it clutters the dependency view.
2023-01-27 12:02:19 -08:00

96 lines
3.6 KiB
C#

using CrystalMpq;
using DiIiS_NA.Core.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Wintellect.PowerCollections;
namespace DiIiS_NA.Core.MPQ
{
public class MPQPatchChain
{
protected static readonly Logger Logger = LogManager.CreateLogger("MPQPatchChain");
public bool Loaded { get; private set; }
public List<string> BaseMPQFiles = new List<string>();
public string PatchPattern { get; private set; }
public int RequiredVersion { get; private set; }
public readonly OrderedMultiDictionary<int, string> MPQFileList = new OrderedMultiDictionary<int, string>(false);
public readonly MpqFileSystem FileSystem = new MpqFileSystem();
protected MPQPatchChain(int requiredVersion, IEnumerable<string> baseFiles, string patchPattern = null)
{
this.Loaded = false;
this.RequiredVersion = requiredVersion;
foreach (var file in baseFiles)
{
var mpqFile = MPQStorage.GetMPQFile(file);
if (mpqFile == null)
{
Logger.Error("Cannot find base MPQ file: {0}.", file);
return;
}
this.BaseMPQFiles.Add(mpqFile);
Logger.Trace("Added MPQ storage: {0}.", file);
}
this.PatchPattern = patchPattern;
this.ConstructChain();
var topMostMPQVersion = this.MPQFileList.Reverse().First().Key; // check required version.
if (topMostMPQVersion == this.RequiredVersion)
this.Loaded = true;
else
{
Logger.Error("Required patch-chain version {0} is not satified (found version: {1}).", this.RequiredVersion, topMostMPQVersion);
}
}
private void ConstructChain()
{
// add base mpq files;
foreach (var mpqFile in this.BaseMPQFiles)
{
MPQFileList.Add(0, mpqFile);
}
if (PatchPattern == null) return;
/* match the mpq files for the patch chain */
var patchRegex = new Regex(this.PatchPattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
foreach (var file in MPQStorage.MPQList)
{
var match = patchRegex.Match(file);
if (!match.Success) continue;
if (!match.Groups["version"].Success) continue;
var patchName = match.Groups[0].Value;
var patchVersion = Int32.Parse(match.Groups["version"].Value);
if (patchVersion > this.RequiredVersion) // ignore the patch if it's version is higher than our required.
{
Logger.Trace("Ignoring patch file {0}.", patchName);
continue;
}
MPQFileList.Add(patchVersion, file);
Logger.Trace("Found patch file: {0}.", patchName);
}
/* add mpq's to mpq-file system in reverse-order (highest version first) */
foreach (var pair in this.MPQFileList.Reverse())
{
foreach (var mpq in pair.Value)
{
Logger.Trace("MPQ: {0}, added to the system.", System.IO.Path.GetFileName(mpq));
this.FileSystem.Archives.Add(new MpqArchive(new FileStream(mpq, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), true));
}
}
Logger.Trace("MPQ system constructed.");
}
}
}