JD2022-TU1/main/tools/apps/JDSongConverter/JDSongFinder.cs

221 lines
8.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Xml;
using JD.Serialization;
using JDSongConverter.Utils;
using Path = System.IO.Path;
namespace JDSongConverter
{
/// <summary>
/// The role of this class is to parse a directory, find all songs, and parse all useful informations about the songs
/// </summary>
public class JDSongFinder
{
/// <summary>
/// Find every songs in a set of paths
/// </summary>
/// <param name="paths">a set of paths</param>
/// <returns></returns>
public IEnumerable<JDSong> FindSongs(IEnumerable<string> paths)
{
foreach (var path in paths)
{
foreach (var song in FindSongs(path, 1))
{
yield return song;
}
}
}
public IEnumerable<JDSong> FindSongs(string path, int maxdepth = 2)
{
var songFound = GetSongFrompath(path);
if (songFound != null)
{
yield return songFound;
}
else if (maxdepth > 0)
{
if (Directory.Exists(path) && Path.GetFileName(path) != "JDBlocks")
{
var subDirs = Directory.EnumerateDirectories(path);
foreach (var subdir in subDirs)
{
foreach (var song in FindSongs(subdir, maxdepth - 1))
{
yield return song;
}
}
}
}
}
public JDSong GetSongFrompath(string path)
{
var songName = ResolveSongName(path);
var layout = ResolveSongLayout(path, songName);
if (layout == JDFolderLayout.Unknown)
return null;
var version = ResolveSongVersion(path, songName, layout);
if (version == JDSongVersion.Unknown)
return null;
var playerCount = ResolvePlayerCount(path, songName, version, layout);
if (playerCount <= 0)
return null;
return new JDSong
{
Name = songName,
RootPath = path,
Version = version,
FolderLayout = layout,
PlayerCount = playerCount
};
}
private string ResolveSongName(string path)
{
var songName = Path.GetFileName(path);
if (string.IsNullOrEmpty(songName)) //in case path is ending with / or \\
{
songName = Directory.GetParent(path).Name;
}
return songName;
}
private JDFolderLayout ResolveSongLayout(string path, string songName)
{
foreach (JDSongVersion jdSongVersion in Enum.GetValues(typeof(JDSongVersion)))
{
foreach (JDFolderLayout jdFolderLayout in Enum.GetValues(typeof(JDFolderLayout)))
{
if (jdFolderLayout == JDFolderLayout.Unknown)
continue;
var wavFile = AppDefinitions.Default.AbsoluteMapPath(MapPathType.WavFile, path, songName, jdSongVersion, jdFolderLayout);
var trkFile = AppDefinitions.Default.AbsoluteMapPath(MapPathType.TrkFile, path, songName, jdSongVersion, jdFolderLayout);
var danceTapeFile = AppDefinitions.Default.AbsoluteMapPath(MapPathType.DanceTapeFile, path, songName, jdSongVersion, jdFolderLayout);
var timelineIscFile = AppDefinitions.Default.AbsoluteMapPath(MapPathType.TimelineIsc, path, songName, jdSongVersion, jdFolderLayout);
if (FileUtils.FastFileExists(wavFile) || FileUtils.FastFileExists(trkFile) || FileUtils.FastFileExists(danceTapeFile) || FileUtils.FastFileExists(timelineIscFile))
{
return jdFolderLayout;
}
}
}
return JDFolderLayout.Unknown;
}
private JDSongVersion ResolveSongVersion(string path, string songName, JDFolderLayout layout)
{
try
{
var tmlFile = AppDefinitions.Default.AbsoluteMapPath(MapPathType.TimelineTml, path, songName, JDSongVersion.JD4, layout);
var tplFile = AppDefinitions.Default.AbsoluteMapPath(MapPathType.TimelineTpl, path, songName, JDSongVersion.JD5, layout);
var dtapeFile = AppDefinitions.Default.AbsoluteMapPath(MapPathType.DanceTapeFile, path, songName, JDSongVersion.JD2015, layout);
var songdescFile = AppDefinitions.Default.AbsoluteMapPath(MapPathType.SongDescFile, path, songName, JDSongVersion.JD2016, layout);
if (File.Exists(songdescFile))
{
LuaSerializer serializer = new LuaSerializer();
var actorTpl = (Actor_Template)serializer.LoadObjectFromFile(songdescFile);
if (actorTpl != null)
{
JD_SongDescTemplate temp = actorTpl.COMPONENTS.OfType<JD_SongDescTemplate>().FirstOrDefault();
if (temp.IsNewFormat)
{
return JDSongVersion.JD2016;
}
}
}
if (File.Exists(dtapeFile))
{
return JDSongVersion.JD2015;
}
if (File.Exists(tplFile))
{
return JDSongVersion.JD5;
}
if (File.Exists(tmlFile))
{
using (XmlReader reader = XmlReader.Create(tmlFile))
{
reader.ReadToFollowing("JustDanceToolLD");
reader.MoveToAttribute("version");
double tmlVersion = Double.Parse(reader.Value, CultureInfo.InvariantCulture);
if (tmlVersion > 9)
{
return JDSongVersion.JD4;
}
else if (tmlVersion > 7)
{
return JDSongVersion.JD3;
}
else
{
return JDSongVersion.JD2;
}
}
}
return JDSongVersion.Unknown;
}
catch (Exception)
{
return JDSongVersion.Unknown;
}
}
private int ResolvePlayerCount(string path, string songName, JDSongVersion version, JDFolderLayout layout)
{
string fileToRead = "";
if (version == JDSongVersion.JD1 ||
version == JDSongVersion.JD2 ||
version == JDSongVersion.JD3 ||
version == JDSongVersion.JD4)
{
fileToRead = AppDefinitions.Default.AbsoluteMapPath(MapPathType.TimelineTml, path, songName, version, layout);
}
else if (version == JDSongVersion.JD5)
{
fileToRead = AppDefinitions.Default.AbsoluteMapPath(MapPathType.TimelineTpl, path, songName, version, layout);
}
else if (version == JDSongVersion.JD2015 ||
version == JDSongVersion.JD2016)
{
fileToRead = AppDefinitions.Default.AbsoluteMapPath(MapPathType.DanceTapeFile, path, songName, version, layout);
}
if ((!songName.EndsWith("CMU") && songName.EndsWith("MU")) ||
(songName.EndsWith("PM")))
{
var mainSongName = songName.Substring(0, songName.Length - 2);
fileToRead = fileToRead.Replace(songName, mainSongName);
}
try
{
var text = File.ReadAllText(fileToRead);
for (int i = 6; i > 0; i--)
{
var moveLayerName = string.Format("Moves{0}", i);
var kinectMoveLayerName = string.Format("KinectMoves{0}", i);
if (text.Contains(moveLayerName) || text.Contains(kinectMoveLayerName))
{
return i;
}
}
}
catch (Exception)
{
return 0;
}
return 1;
}
}
}