Files
crtr/Assets/Cryville/Crtr/Browsing/LegacyResourceManager.cs

202 lines
6.6 KiB
C#

using Cryville.Common;
using Cryville.Common.Unity;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
using Logger = Cryville.Common.Logger;
namespace Cryville.Crtr.Browsing {
internal class LegacyResourceManager : IResourceManager<ChartDetail> {
private readonly string _rootPath;
private DirectoryInfo cd;
private DirectoryInfo[] items = new DirectoryInfo[0];
public string[] CurrentDirectory { get; private set; }
static readonly Dictionary<string, List<ResourceConverter>> converters
= new Dictionary<string, List<ResourceConverter>>();
public LegacyResourceManager(string rootPath) {
_rootPath = rootPath;
}
static LegacyResourceManager() {
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies()) {
foreach (var type in asm.GetTypes()) {
if (type.IsSubclassOf(typeof(ResourceConverter))) {
var converter = (ResourceConverter)Activator.CreateInstance(type);
foreach (var f in converter.GetSupportedFormats()) {
if (!converters.ContainsKey(f))
converters.Add(f, new List<ResourceConverter> { converter });
else converters[f].Add(converter);
}
}
}
}
}
public int ChangeDirectory(string[] dir) {
CurrentDirectory = dir;
cd = new DirectoryInfo(_rootPath + "/charts/" + string.Join("/", dir));
items = cd.GetDirectories();
return items.Length;
}
public int OpenDirectory(int id) {
string[] nd = new string[CurrentDirectory.Length + 1];
Array.Copy(CurrentDirectory, nd, CurrentDirectory.Length);
nd[CurrentDirectory.Length] = items[id].Name;
return ChangeDirectory(nd);
}
public int ReturnToDirectory(int id) {
string[] nd = new string[id + 1];
Array.Copy(CurrentDirectory, nd, id + 1);
return ChangeDirectory(nd);
}
public ResourceItemMeta GetItemMeta(int id) {
var item = items[id];
var meta = new ChartMeta();
string name = item.Name;
string desc = "(Unknown)";
var metaFile = new FileInfo(item.FullName + "/.umgc");
if (metaFile.Exists) {
using (var reader = new StreamReader(metaFile.FullName)) {
meta = JsonConvert.DeserializeObject<ChartMeta>(reader.ReadToEnd());
name = meta.song.name;
desc = meta.name;
}
}
AsyncDelivery<Texture2D> cover = null;
if (meta.cover != null && meta.cover != "") {
var coverFile = item.GetFiles(meta.cover);
if (coverFile.Length > 0) {
cover = new AsyncDelivery<Texture2D>();
var task = new LoadTextureTask(Game.FileProtocolPrefix + coverFile[0].FullName, cover.Deliver);
cover.CancelSource = task.Cancel;
Game.NetworkTaskWorker.SubmitNetworkTask(task);
}
}
return new ResourceItemMeta {
IsDirectory = false,
Icon = cover,
Name = name,
DescriptionMain = desc,
};
}
public ChartDetail GetItemDetail(int id) {
var item = items[id];
var meta = new ChartMeta();
var metaFile = new FileInfo(item.FullName + "/.umgc");
if (metaFile.Exists) {
using (var reader = new StreamReader(metaFile.FullName)) {
meta = JsonConvert.DeserializeObject<ChartMeta>(reader.ReadToEnd());
}
}
AsyncDelivery<Texture2D> cover = null;
if (meta.cover != null && meta.cover != "") {
var coverFile = item.GetFiles(meta.cover);
if (coverFile.Length > 0) {
cover = new AsyncDelivery<Texture2D>();
var task = new LoadTextureTask(Game.FileProtocolPrefix + coverFile[0].FullName, cover.Deliver);
cover.CancelSource = task.Cancel;
Game.NetworkTaskWorker.SubmitNetworkTask(task);
}
}
return new ChartDetail {
Cover = cover,
Meta = meta,
};
}
public string GetItemPath(int id) {
var item = items[id];
var meta = new ChartMeta();
var metaFile = new FileInfo(item.FullName + "/.umgc");
using (var reader = new StreamReader(metaFile.FullName)) {
meta = JsonConvert.DeserializeObject<ChartMeta>(reader.ReadToEnd());
}
return string.Format("{0}/{1}.json", items[id].Name, meta.data);
}
public bool ImportItemFrom(string path) {
var file = new FileInfo(path);
if (!converters.ContainsKey(file.Extension)) return false;
foreach (var converter in converters[file.Extension]) {
IEnumerable<Resource> resources = null;
try {
resources = converter.ConvertFrom(file);
}
catch (Exception ex) {
LogAndPopup(4, ex.Message);
return false;
}
foreach (var res in resources) {
if (!res.Valid) {
LogAndPopup(3, "Attempt to import invalid resource: {0}", res);
}
else if (res is RawChartResource) {
var tres = (RawChartResource)res;
var dir = new DirectoryInfo(_rootPath + "/charts/" + res.Name);
if (!dir.Exists) dir.Create();
using (var writer = new StreamWriter(dir.FullName + "/.json")) {
writer.Write(JsonConvert.SerializeObject(tres.Main, Game.GlobalJsonSerializerSettings));
}
using (var writer = new StreamWriter(dir.FullName + "/.umgc")) {
tres.Meta.data = "";
writer.Write(JsonConvert.SerializeObject(tres.Meta, Game.GlobalJsonSerializerSettings));
}
if (tres.Meta.cover != null) {
var coverFile = new FileInfo(Path.Combine(file.Directory.FullName, tres.Meta.cover));
if (coverFile.Exists)
coverFile.CopyTo(Path.Combine(dir.FullName, tres.Meta.cover), true);
}
}
else if (res is FileResource) {
var tres = (FileResource)res;
DirectoryInfo dest;
if (res is ChartResource)
dest = new DirectoryInfo(_rootPath + "/charts/" + res.Name);
else if (res is RulesetResource)
dest = new DirectoryInfo(_rootPath + "/rulesets/" + res.Name);
else if (res is SkinResource)
dest = new DirectoryInfo(_rootPath + "/skins/" + (res as SkinResource).RulesetName + "/" + res.Name);
else if (res is SongResource)
dest = new DirectoryInfo(_rootPath + "/songs/" + res.Name);
else {
LogAndPopup(3, "Attempt to import unsupported file resource: {0}", res);
continue;
}
if (!dest.Exists) {
dest.Create();
tres.Master.CopyTo(Path.Combine(dest.FullName, tres.Master.Extension));
foreach (var attachment in tres.Attachments) {
attachment.CopyTo(Path.Combine(dest.FullName, attachment.Name));
}
}
else LogAndPopup(1, "Resource already exists: {0}", res);
}
else {
LogAndPopup(3, "Attempt to import unsupported resource: {0}", res);
}
}
return true;
}
return false;
}
void LogAndPopup(int level, string format, params object[] args) {
var msg = string.Format(format, args);
Logger.Log("main", level, "Resource", msg);
Popup.Create(msg);
}
public string[] GetSupportedFormats() {
return converters.Keys.ToArray();
}
}
}