JD2022-TU1/main/tools/apps/Packager/Tasks/BundleStatsTask.cs

144 lines
5 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using Packager.Parameters;
using PluginCommon.Bundle;
namespace Packager.Tasks
{
[DisplayName(@"Bundle Stats")]
public class BundleStatsTask : Task
{
private const string UnknownMapType = "Unknown";
private const string CkdExtention = ".ckd";
private const string StatFilename = "ipk_stats.csv";
private const string BundleExtention = ".ipk";
private static readonly string[] PatternsToFind = { "_MAIN_SCENE_", "_", BundleExtention };
private static readonly Dictionary<string, string> MapTypes = new Dictionary<string, string>
{
{ "ALT", "Alternate" },
{ "OSC", "On Stage Choreo" },
{ "SWT", "Sweat" },
{ "SIX", "Six players" },
{ "BAT", "Battle" },
{ "Bundle", "Common"},
{ "BlockFlows", "Move Database" },
{ "_", "Normal" }
};
public BundleStatsTask()
{
FileList = new ReferenceList();
}
[Input("File List", IOCardinality.Multi, IOType.File)]
public ReferenceList FileList { get; set; }
[Output("Stat Files", IOType.File)]
public ReferenceList StatFiles = new ReferenceList();
private string GetMapName(string filename)
{
var firstMatchingIndex = PatternsToFind
.Select(pattern => filename.IndexOf(pattern, StringComparison.OrdinalIgnoreCase))
.FirstOrDefault(index => index >= 0);
return firstMatchingIndex > 0 ? filename.Substring(0, firstMatchingIndex) : filename;
}
private string GetMapType(string filename)
{
var mapType = MapTypes.Where(keyValue => filename.IndexOf(keyValue.Key, StringComparison.OrdinalIgnoreCase) >= 0)
.Select(keyValue => keyValue.Value)
.FirstOrDefault();
return !string.IsNullOrEmpty(mapType) ? mapType : UnknownMapType;
}
private IpkStats GetStatsFromIPK(string ipkFilename)
{
var ipkStats = new IpkStats();
using (var bundle = new Bundle(ipkFilename))
{
var files = bundle.FileList;
foreach (var filename in files)
{
var correctedFilename = filename.EndsWith(CkdExtention) ? filename.Substring(0, filename.Length - CkdExtention.Length) : filename;
var extention = Path.GetExtension(correctedFilename);
var fileSize = bundle.GetFileHeader(filename).RuntimeHeader.SizeInBundle;
ipkStats.AddFile(extention, fileSize);
}
}
return ipkStats;
}
protected override void StartInternal(BuildConfiguration profile, cookerWrapper cooker)
{
var bundleFiles = FileList.Where(file => Path.GetExtension(file).CompareTo(BundleExtention) == 0);
try
{
var bundleStats = bundleFiles.Select(file => new { FullPath = file, new FileInfo(file).Length });
var allOutputLines = new List<string> { string.Join(";", "Map name", "Map type", "File name", "Total Length", "Video data", "Audio data") };
foreach (var stats in bundleStats)
{
var filename = Path.GetFileName(stats.FullPath);
var mapName = GetMapName(filename);
var mapType = GetMapType(filename);
var ipkStats = GetStatsFromIPK(stats.FullPath);
var videoStats = ipkStats.ExtentionSize(".webm");
var waveStats = ipkStats.ExtentionSize(".wav");
var statFormatedOutput = string.Join(";", mapName, mapType, filename, stats.Length.ToString(), videoStats.ToString(), waveStats.ToString());
allOutputLines.Add(statFormatedOutput);
LogMessage(false, statFormatedOutput);
}
var outputFile = Path.Combine(TaskOutputFolder, StatFilename);
File.WriteAllLines(outputFile, allOutputLines);
StatFiles.Add(outputFile);
}
catch (Exception ex)
{
LogMessage(true, ex.Message);
}
}
private class IpkStats
{
private readonly Dictionary<string, uint> _statsByType = new Dictionary<string, uint>();
public void AddFile(string extention, uint fileSize)
{
if (!_statsByType.ContainsKey(extention))
{
_statsByType[extention] = 0;
}
_statsByType[extention] += fileSize;
}
public uint ExtentionSize(string extention)
{
uint value;
_statsByType.TryGetValue(extention, out value);
return value;
}
}
}
}