2020-03-10 19:50:02 +08:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.ComponentModel;
|
2020-03-11 21:05:49 +08:00
|
|
|
|
using System.Runtime.InteropServices;
|
2020-03-10 19:50:02 +08:00
|
|
|
|
using System.Text;
|
|
|
|
|
|
|
|
|
|
namespace CodeWalker.GameFiles
|
|
|
|
|
{
|
|
|
|
|
[TypeConverter(typeof(ExpandableObjectConverter))]
|
|
|
|
|
public class ResourceAnalyzer
|
|
|
|
|
{
|
2020-03-18 02:32:16 +08:00
|
|
|
|
public RpfResourceFileEntry FileEntry { get; set; }
|
|
|
|
|
public ResourcePagesInfo FilePagesInfo { get; set; }
|
|
|
|
|
public RpfResourcePage[] SystemPages { get; set; }
|
|
|
|
|
public RpfResourcePage[] GraphicsPages { get; set; }
|
2020-03-10 19:50:02 +08:00
|
|
|
|
public ResourceAnalyzerItem[] Blocks { get; set; }
|
|
|
|
|
|
|
|
|
|
[TypeConverter(typeof(ExpandableObjectConverter))]
|
|
|
|
|
public class ResourceAnalyzerItem
|
|
|
|
|
{
|
|
|
|
|
public long Position { get; set; }
|
|
|
|
|
public long Length { get; set; }
|
|
|
|
|
public long Offset { get { return Position & 0xFFFFFFF; } }
|
2020-03-11 21:05:49 +08:00
|
|
|
|
public bool Overlapping { get; set; }
|
2020-03-10 19:50:02 +08:00
|
|
|
|
public ResourceSystemBlock SystemBlock { get; set; }
|
|
|
|
|
public ResourceGraphicsBlock GraphicsBlock { get; set; }
|
2020-03-11 21:05:49 +08:00
|
|
|
|
public Array Array { get; set; }
|
2020-03-11 22:33:57 +08:00
|
|
|
|
public string String { get; set; }
|
2020-03-11 21:05:49 +08:00
|
|
|
|
|
2020-03-10 19:50:02 +08:00
|
|
|
|
|
|
|
|
|
public override string ToString()
|
|
|
|
|
{
|
2020-03-11 21:05:49 +08:00
|
|
|
|
var type = "########## ??? ##########";
|
2020-03-20 01:54:59 +08:00
|
|
|
|
var val = "";
|
2020-03-10 19:50:02 +08:00
|
|
|
|
if (SystemBlock != null)
|
|
|
|
|
{
|
|
|
|
|
type = SystemBlock.GetType().Name;
|
2020-03-20 01:54:59 +08:00
|
|
|
|
//val = SystemBlock.ToString();
|
2020-03-10 19:50:02 +08:00
|
|
|
|
}
|
2020-03-11 22:33:57 +08:00
|
|
|
|
else if (GraphicsBlock != null)
|
2020-03-10 19:50:02 +08:00
|
|
|
|
{
|
|
|
|
|
type = GraphicsBlock.GetType().Name;
|
2020-03-20 01:54:59 +08:00
|
|
|
|
//val = GraphicsBlock.ToString();
|
2020-03-10 19:50:02 +08:00
|
|
|
|
}
|
2020-03-11 22:33:57 +08:00
|
|
|
|
else if (Array != null)
|
2020-03-11 21:05:49 +08:00
|
|
|
|
{
|
|
|
|
|
type = Array.GetType().Name + " (" + Array.Length.ToString() + ")";
|
|
|
|
|
}
|
2020-03-11 22:33:57 +08:00
|
|
|
|
else if (String != null)
|
|
|
|
|
{
|
2020-03-20 01:54:59 +08:00
|
|
|
|
type = "string";
|
|
|
|
|
val = "\"" + String + "\"";
|
2020-03-11 22:33:57 +08:00
|
|
|
|
}
|
2020-03-20 01:54:59 +08:00
|
|
|
|
var valstr = (string.IsNullOrEmpty(val) ? "" : " - " + val);
|
|
|
|
|
return Offset.ToString() + " - " + Length.ToString() + " - " + type + valstr + (Overlapping ? " (embedded)" : "");
|
2020-03-10 19:50:02 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ResourceAnalyzer(ResourceDataReader reader)
|
|
|
|
|
{
|
2020-03-18 02:32:16 +08:00
|
|
|
|
FileEntry = reader.FileEntry;
|
|
|
|
|
SystemPages = FileEntry?.SystemFlags.Pages;
|
|
|
|
|
GraphicsPages = FileEntry?.GraphicsFlags.Pages;
|
|
|
|
|
|
2020-03-10 19:50:02 +08:00
|
|
|
|
var dlist = new List<ResourceAnalyzerItem>();
|
2020-03-11 21:05:49 +08:00
|
|
|
|
foreach (var kvp in reader.blockPool)
|
2020-03-10 19:50:02 +08:00
|
|
|
|
{
|
|
|
|
|
var item = new ResourceAnalyzerItem();
|
|
|
|
|
item.Position = kvp.Key;
|
|
|
|
|
item.Length = kvp.Value.BlockLength;
|
|
|
|
|
item.SystemBlock = kvp.Value as ResourceSystemBlock;
|
|
|
|
|
item.GraphicsBlock = kvp.Value as ResourceGraphicsBlock;
|
2020-03-11 22:33:57 +08:00
|
|
|
|
if (kvp.Value is ResourcePagesInfo rpi)
|
|
|
|
|
{
|
2020-03-12 06:45:01 +08:00
|
|
|
|
item.Length = 16 + (rpi.SystemPagesCount + rpi.GraphicsPagesCount) * 8;
|
2020-03-18 02:32:16 +08:00
|
|
|
|
FilePagesInfo = rpi;
|
2020-03-11 22:33:57 +08:00
|
|
|
|
}
|
2020-03-10 19:50:02 +08:00
|
|
|
|
dlist.Add(item);
|
|
|
|
|
}
|
2020-03-11 21:05:49 +08:00
|
|
|
|
foreach (var kvp in reader.arrayPool)
|
|
|
|
|
{
|
|
|
|
|
var item = new ResourceAnalyzerItem();
|
|
|
|
|
item.Position = kvp.Key;
|
|
|
|
|
item.Array = kvp.Value as Array;
|
|
|
|
|
if (item.Array != null)
|
|
|
|
|
{
|
|
|
|
|
var typ = item.Array.GetType().GetElementType();
|
|
|
|
|
var siz = Marshal.SizeOf(typ);
|
|
|
|
|
item.Length = item.Array.Length * siz;
|
|
|
|
|
}
|
2020-03-11 22:33:57 +08:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
item.String = kvp.Value as string;
|
|
|
|
|
if (item.String != null)
|
|
|
|
|
{
|
|
|
|
|
item.Length = item.String.Length + 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-03-11 21:05:49 +08:00
|
|
|
|
dlist.Add(item);
|
|
|
|
|
}
|
2020-03-10 19:50:02 +08:00
|
|
|
|
|
|
|
|
|
dlist.Sort((a, b) => a.Position.CompareTo(b.Position));
|
|
|
|
|
|
2020-03-11 21:05:49 +08:00
|
|
|
|
//Blocks = dlist.ToArray();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var dlist2 = new List<ResourceAnalyzerItem>();
|
|
|
|
|
long pos = 0;
|
2020-03-12 06:45:01 +08:00
|
|
|
|
bool gfx = false;
|
2020-03-11 21:05:49 +08:00
|
|
|
|
foreach (var item in dlist)
|
|
|
|
|
{
|
2020-03-12 06:45:01 +08:00
|
|
|
|
if ((item.GraphicsBlock != null) && (!gfx))
|
|
|
|
|
{
|
|
|
|
|
pos = 0;
|
|
|
|
|
gfx = true;
|
|
|
|
|
}
|
2020-03-11 21:05:49 +08:00
|
|
|
|
if (item.Offset > pos)
|
|
|
|
|
{
|
|
|
|
|
var gap = new ResourceAnalyzerItem();
|
|
|
|
|
gap.Position = pos;
|
|
|
|
|
gap.Length = item.Offset - pos;
|
|
|
|
|
dlist2.Add(gap);
|
|
|
|
|
pos = item.Offset;
|
|
|
|
|
}
|
|
|
|
|
if (item.Offset == pos)
|
|
|
|
|
{
|
|
|
|
|
dlist2.Add(item);
|
|
|
|
|
pos = item.Offset + item.Length;
|
2020-03-11 22:33:57 +08:00
|
|
|
|
if (item.String == null)
|
|
|
|
|
{
|
|
|
|
|
if ((pos % 16) != 0) pos += (16 - (pos % 16));//ignore alignment paddings
|
|
|
|
|
}
|
2020-03-11 21:05:49 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
item.Overlapping = true;
|
|
|
|
|
dlist2.Add(item);
|
|
|
|
|
var pos2 = item.Offset + item.Length;
|
|
|
|
|
if (pos2 > pos) pos = pos2;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Blocks = dlist2.ToArray();
|
2020-03-10 19:50:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
2020-03-11 21:05:49 +08:00
|
|
|
|
|
2020-03-10 19:50:02 +08:00
|
|
|
|
}
|
|
|
|
|
}
|