using AnotherReplayReader.Utils; using Microsoft.Win32; using System; using System.IO; using System.Linq; using System.Reflection; 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().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 (ReflectionTypeLoadException e) { Debug.Instance.DebugMessage += $"Exception during initialization of BigMinimapCache: \r\n{e}\r\nLoader Exceptions: {e.LoaderExceptions.Length}"; foreach (var e2 in e.LoaderExceptions) { Debug.Instance.DebugMessage += $"Exception during initialization of BigMinimapCache: \r\n{e2}\r\n"; } } catch (Exception exception) { Debug.Instance.DebugMessage += $"Exception during initialization of BigMinimapCache: \r\n{exception}\r\n"; } } } }