AnotherReplayReader/BigMinimapCache.cs

112 lines
4.2 KiB
C#

using AnotherReplayReader.Utils;
using Microsoft.Win32;
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using TechnologyAssembler.Core.IO;
namespace AnotherReplayReader
{
internal sealed class BigMinimapCache
{
private readonly object _lock = new();
private SkuDefFileSystemProvider? _skudefFileSystem = null;
public BigMinimapCache(string? ra3Directory)
{
Task.Run(() => Initialize(ra3Directory));
}
public bool TryGetEntry(string path, out Stream? bigEntry)
{
bigEntry = null;
using var locker = new Lock(_lock);
if (_skudefFileSystem is not { } fs)
{
return false;
}
if (!fs.FileExists(path))
{
Debug.Instance.DebugMessage += $"Cannot find big entry [{path}].\r\n";
return false;
}
try
{
bigEntry = fs.OpenStream(path, VirtualFileModeType.Open);
return true;
}
catch (Exception exception)
{
Debug.Instance.DebugMessage += $"Exception during query (entryStream) of BigMinimapCache: \r\n{exception}\r\n";
}
return false;
}
private void Initialize(string? ra3Directory)
{
try
{
if (ra3Directory is null || !Directory.Exists(ra3Directory))
{
Debug.Instance.DebugMessage += $"Will not initialize BigMinimapCache because RA3Directory {ra3Directory} does not exist.\r\n";
return;
}
var currentLanguage = RegistryUtils.RetrieveInRa3(RegistryHive.CurrentUser, "Language");
var currentLanguage_ = $"{currentLanguage}_";
double SkudefVersionSelector(string fullPath)
{
var value = -1.0;
try
{
const string skudefPrefix = "RA3";
const int prefix = 1;
const int language = 2;
const int majorVersion = 3;
const int minorVersion = 4;
const int majorVersionMultiplier = 10000;
const int correctLanguageBonus = 1000_0000;
value = 0;
var stem = Path.GetFileNameWithoutExtension(fullPath);
var match = Regex.Match(stem, @"([^_]*)_([^0-9]*)([0-9]*)\.([0-9]*)");
if (!match.Success || match.Groups.Cast<Group>().Any(g => !g.Success))
{
return value;
}
value += match.Groups[prefix].Value == skudefPrefix ? 0.1 : 0;
value += match.Groups[language].Value == currentLanguage_ ? correctLanguageBonus : 0;
value += int.Parse(match.Groups[majorVersion].Value) * majorVersionMultiplier;
value += int.Parse(match.Groups[minorVersion].Value);
return value;
}
catch (Exception e)
{
Debug.Instance.DebugMessage += $"Failed to retrieve skudef: {e}\r\n";
}
return value;
}
var highestSkudef = (from p in Directory.EnumerateFiles(ra3Directory, "*.SkuDef")
orderby SkudefVersionSelector(p) descending
select p).First();
Debug.Instance.DebugMessage += $"Retrieved highest skudef: {highestSkudef}\r\n";
using var locker = new Lock(_lock);
DronePlatform.BuildTechnologyAssembler();
_skudefFileSystem = new SkuDefFileSystemProvider("config", highestSkudef);
}
catch (Exception exception)
{
Debug.Instance.DebugMessage += $"Exception during initialization of BigMinimapCache: \r\n{exception}\r\n";
}
}
}
}