Add project files.
This commit is contained in:
231
BigMinimapCache.cs
Normal file
231
BigMinimapCache.cs
Normal file
@@ -0,0 +1,231 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Win32;
|
||||
using OpenSage.FileFormats.Big;
|
||||
|
||||
namespace AnotherReplayReader
|
||||
{
|
||||
internal sealed class BigMinimapCache
|
||||
{
|
||||
private sealed class CacheAdapter
|
||||
{
|
||||
public List<string> Bigs { get; set; }
|
||||
public Dictionary<string, string> MapsToBigs { get; set; }
|
||||
|
||||
public CacheAdapter()
|
||||
{
|
||||
Bigs = new List<string>();
|
||||
MapsToBigs = new Dictionary<string, string>();
|
||||
}
|
||||
}
|
||||
|
||||
//private Cache _cache;
|
||||
private volatile IReadOnlyDictionary<string, string> _mapsToBigs = null;
|
||||
|
||||
public BigMinimapCache(Cache cache, string ra3Directory)
|
||||
{
|
||||
//_cache = cache;
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Directory.Exists(ra3Directory))
|
||||
{
|
||||
Debug.Instance.DebugMessage += $"Will not initialize BigMinimapCache because RA3Directory {ra3Directory} does not exist.\r\n";
|
||||
return;
|
||||
}
|
||||
|
||||
var bigSet = ParseSkudefs(Directory.EnumerateFiles(ra3Directory, "*.SkuDef"));
|
||||
|
||||
//var cached = _cache.GetOrDefault("bigsCache", new CacheAdapter());
|
||||
var mapsToBigs = new Dictionary<string, string>();
|
||||
|
||||
foreach (var bigPath in bigSet/*.Where(x => !cached.Bigs.Contains(x))*/)
|
||||
{
|
||||
if (!File.Exists(bigPath))
|
||||
{
|
||||
Debug.Instance.DebugMessage += $"Big {bigPath} does not exist.\r\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
Debug.Instance.DebugMessage += $"Trying to add Big {bigPath} to big minimap cache...\r\n";
|
||||
try
|
||||
{
|
||||
using (var big = new BigArchive(bigPath))
|
||||
{
|
||||
foreach (var entry in big.Entries)
|
||||
{
|
||||
if (entry.FullName.EndsWith("_art.tga", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
mapsToBigs[entry.FullName] = bigPath;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception exception)
|
||||
{
|
||||
Debug.Instance.DebugMessage += $"Exception when reading big:\r\n {exception}\r\n";
|
||||
}
|
||||
}
|
||||
//cached.Bigs = bigSet.ToList();
|
||||
|
||||
//_cache.Set("bigsCache", cached);
|
||||
_mapsToBigs = mapsToBigs; //cached.MapsToBigs;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Debug.Instance.DebugMessage += $"Exception during initialization of BigMinimapCache: \r\n{exception}\r\n";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static HashSet<string> ParseSkudefs(IEnumerable<string> skudefs)
|
||||
{
|
||||
var skudefSet = new HashSet<string>(skudefs.Select(x => x.ToLowerInvariant()));
|
||||
var unreadSkudefs = new HashSet<string>();
|
||||
var bigSet = new HashSet<string>();
|
||||
|
||||
void ReadSkudefLine(string baseDirectory, string line, string expectedCommand, Action<string> action)
|
||||
{
|
||||
try
|
||||
{
|
||||
char[] separators = { ' ', '\t' };
|
||||
line = line.ToLowerInvariant();
|
||||
var splitted = line.Split(separators, 2, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (splitted[0].Equals(expectedCommand))
|
||||
{
|
||||
var path = splitted[1];
|
||||
if (!Path.IsPathRooted(path))
|
||||
{
|
||||
path = Path.Combine(baseDirectory, path);
|
||||
}
|
||||
action(path);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Debug.Instance.DebugMessage += $"Exception when parsing skudef line:\r\n {exception}\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
void ReadSkudef(string fileName, Action<string, string> onBaseDirectoryAndLine)
|
||||
{
|
||||
try
|
||||
{
|
||||
var baseDirectory = Path.GetDirectoryName(fileName).ToLowerInvariant();
|
||||
foreach (var line in File.ReadAllLines(fileName))
|
||||
{
|
||||
onBaseDirectoryAndLine(baseDirectory, line);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Debug.Instance.DebugMessage += $"Exception when parsing skudef file:\r\n {exception}\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var skudef in skudefSet)
|
||||
{
|
||||
ReadSkudef(skudef, (baseDirectory, line) =>
|
||||
{
|
||||
ReadSkudefLine(baseDirectory, line, "add-config", x =>
|
||||
{
|
||||
if (!skudefSet.Contains(x))
|
||||
{
|
||||
unreadSkudefs.Add(x);
|
||||
}
|
||||
});
|
||||
|
||||
ReadSkudefLine(baseDirectory, line, "add-big", x => bigSet.Add(x));
|
||||
});
|
||||
}
|
||||
|
||||
foreach (var skudef in unreadSkudefs)
|
||||
{
|
||||
ReadSkudef(skudef, (baseDirectory, line) =>
|
||||
{
|
||||
ReadSkudefLine(baseDirectory, line, "add-big", x => bigSet.Add(x));
|
||||
});
|
||||
}
|
||||
|
||||
return bigSet;
|
||||
}
|
||||
|
||||
public bool TryGetBigByEntryPath(string path, out BigArchive big)
|
||||
{
|
||||
big = null;
|
||||
|
||||
if (_mapsToBigs == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_mapsToBigs.ContainsKey(path))
|
||||
{
|
||||
Debug.Instance.DebugMessage += $"Cannot find big entry [{path}].\r\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var bigPath = _mapsToBigs[path];
|
||||
big = new BigArchive(bigPath);
|
||||
if(big.GetEntry(path) == null)
|
||||
{
|
||||
//_cache.Remove("bigsCache");
|
||||
big.Dispose();
|
||||
big = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Debug.Instance.DebugMessage += $"Exception during query (entryStream) of BigMinimapCache: \r\n{exception}\r\n";
|
||||
big = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public byte[] TryReadBytesFromBig(string path)
|
||||
{
|
||||
if(_mapsToBigs == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if(!_mapsToBigs.ContainsKey(path))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var bigPath = _mapsToBigs[path];
|
||||
using (var big = new BigArchive(path))
|
||||
{
|
||||
var entry = big.GetEntry(path);
|
||||
using (var stream = entry.Open())
|
||||
using (var reader = new BinaryReader(stream))
|
||||
{
|
||||
return reader.ReadBytes((int)entry.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Debug.Instance.DebugMessage += $"Exception during query (bytes) of BigMinimapCache: \r\n{exception}\r\n";
|
||||
//_cache.Remove("bigsCache");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user