AxibugEmuOnline/AxibugEmuOnline.Client/Assets/Script/Manager/RomLib/RomFile.cs

146 lines
5.1 KiB
C#
Raw Normal View History

2024-08-14 13:09:22 +08:00
using AxibugEmuOnline.Client.ClientCore;
using ICSharpCode.SharpZipLib.Zip;
using System;
using System.Collections;
2024-08-13 18:35:20 +08:00
using System.IO;
2024-08-14 13:09:22 +08:00
using UnityEngine.Networking;
2024-08-13 18:35:20 +08:00
namespace AxibugEmuOnline.Client
{
public class RomFile
{
private HttpAPI.Resp_RomInfo webData;
private bool hasLocalFile;
2024-08-14 13:09:22 +08:00
private string fileName;
2024-08-13 18:35:20 +08:00
private EnumPlatform platform;
2024-09-11 16:33:48 +08:00
private UnityWebRequest downloadRequest;
2024-08-13 18:35:20 +08:00
2024-08-22 15:16:58 +08:00
/// <summary> 指示该Rom文件的存放路径 </summary>
2024-09-11 18:31:25 +08:00
public string LocalFilePath => $"{App.PersistentDataPath}/RemoteRoms/{platform}/{fileName}";
2024-08-22 15:16:58 +08:00
/// <summary> 指示该Rom文件是否已下载完毕 </summary>
public bool RomReady => hasLocalFile;
/// <summary> 指示是否正在下载Rom文件 </summary>
2024-09-11 16:33:48 +08:00
public bool IsDownloading => downloadRequest != null && downloadRequest.result == UnityWebRequest.Result.InProgress;
public float Progress => IsDownloading ? downloadRequest.downloadProgress : 0;
2024-08-22 15:16:58 +08:00
2024-09-11 16:33:48 +08:00
public EnumPlatform Platform => platform;
2024-08-22 15:16:58 +08:00
/// <summary> 指示该Rom信息是否已填充 </summary>
public bool InfoReady => webData != null;
/// <summary> 唯一标识 </summary>
public int ID => webData != null ? webData.id : -1;
/// <summary> 别名 </summary>
2024-08-14 13:09:22 +08:00
public string Alias => webData.romName;
2024-08-22 15:16:58 +08:00
/// <summary> 描述 </summary>
public string Descript => webData.desc;
2024-08-22 17:25:00 +08:00
/// <summary> 小图URL </summary>
public string ImageURL => webData.imgUrl;
2024-08-22 15:16:58 +08:00
/// <summary> 文件名 </summary>
2024-08-14 13:09:22 +08:00
public string FileName => fileName;
2024-08-22 15:16:58 +08:00
/// <summary> 在查询结果中的索引 </summary>
public int Index { get; private set; }
/// <summary> 在查询结果中的所在页 </summary>
public int Page { get; private set; }
2024-08-13 18:35:20 +08:00
2024-08-14 13:09:22 +08:00
public event Action OnDownloadOver;
2024-08-22 15:16:58 +08:00
public event Action OnInfoFilled;
2024-08-13 18:35:20 +08:00
2024-08-22 15:16:58 +08:00
public RomFile(EnumPlatform platform, int index, int insidePage)
2024-08-13 18:35:20 +08:00
{
this.platform = platform;
2024-08-22 15:16:58 +08:00
Index = index;
Page = insidePage;
2024-08-13 18:35:20 +08:00
}
2024-08-14 13:09:22 +08:00
public void BeginDownload()
2024-08-13 18:35:20 +08:00
{
2024-08-22 15:16:58 +08:00
if (RomReady) return;
2024-08-14 13:09:22 +08:00
if (IsDownloading) return;
2024-09-11 18:31:25 +08:00
App.StartCoroutine(DownloadRemoteRom((bytes) =>
2024-08-14 13:09:22 +08:00
{
if (bytes != null)
{
var directPath = Path.GetDirectoryName(LocalFilePath);
Directory.CreateDirectory(directPath);
File.WriteAllBytes(LocalFilePath, bytes);
hasLocalFile = true;
}
OnDownloadOver?.Invoke();
}));
}
public byte[] GetRomFileData()
{
if (webData == null) throw new Exception("Not Valid Rom");
2024-08-22 15:16:58 +08:00
if (!RomReady) throw new Exception("Rom File Not Downloaded");
2024-08-14 13:09:22 +08:00
var bytes = File.ReadAllBytes(LocalFilePath);
if (Path.GetExtension(LocalFilePath).ToLower() == ".zip")
{
var zip = new ZipInputStream(new MemoryStream(bytes));
while (zip.GetNextEntry() is ZipEntry entry)
{
if (!entry.Name.ToLower().EndsWith(".nes")) continue;
var buffer = new byte[1024];
MemoryStream output = new MemoryStream();
while (true)
{
var size = zip.Read(buffer, 0, buffer.Length);
if (size == 0) break;
else output.Write(buffer, 0, size);
}
output.Flush();
return output.ToArray();
}
}
else
2024-08-13 18:35:20 +08:00
{
2024-08-14 13:09:22 +08:00
return bytes;
}
throw new Exception("Not Valid Rom Data");
}
private IEnumerator DownloadRemoteRom(Action<byte[]> callback)
{
2024-09-13 10:07:24 +08:00
downloadRequest = UnityWebRequest.Get($"{App.httpAPI.WebHost}/{webData.url}");
2024-09-11 16:33:48 +08:00
yield return downloadRequest.SendWebRequest();
2024-08-14 13:09:22 +08:00
2024-09-11 16:33:48 +08:00
if (downloadRequest.result != UnityWebRequest.Result.Success)
2024-08-14 13:09:22 +08:00
{
callback(null);
}
else
{
2024-09-11 16:33:48 +08:00
callback(downloadRequest.downloadHandler.data);
2024-08-13 18:35:20 +08:00
}
}
public void SetWebData(HttpAPI.Resp_RomInfo resp_RomInfo)
{
webData = resp_RomInfo;
2024-08-14 13:09:22 +08:00
fileName = Path.GetFileName(webData.url);
2024-08-14 13:20:52 +08:00
fileName = System.Net.WebUtility.UrlDecode(fileName);
2024-08-13 18:35:20 +08:00
if (File.Exists(LocalFilePath))
{
2024-08-14 13:09:22 +08:00
var fileBytes = File.ReadAllBytes(LocalFilePath);
var localHash = RomLib.CalcHash(fileBytes);
hasLocalFile = localHash == webData.hash;
if (!hasLocalFile)
File.Delete(LocalFilePath);
2024-08-13 18:35:20 +08:00
}
else
{
hasLocalFile = false;
}
2024-08-22 15:16:58 +08:00
OnInfoFilled?.Invoke();
2024-08-13 18:35:20 +08:00
}
}
}