CTT/Unity/Assets/Model/XAssetRuntime/Core/Versions.cs

207 lines
6.2 KiB
C#
Raw Normal View History

2021-04-08 20:09:59 +08:00
//
// Versions.cs
//
// Author:
// fjy <jiyuan.feng@live.com>
//
// Copyright (c) 2020 fjy
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
namespace libx
{
public enum VerifyBy
{
Size,
Hash,
}
public static class Versions
{
public const string Dataname = "res";
public const string Filename = "ver";
public static readonly VerifyBy verifyBy = VerifyBy.Hash;
private static readonly VDisk _disk = new VDisk ();
private static readonly Dictionary<string, VFile> _updateData = new Dictionary<string, VFile> ();
private static readonly Dictionary<string, VFile> _baseData = new Dictionary<string, VFile> ();
public static AssetBundle LoadAssetBundleFromFile (string url)
{
if (!File.Exists (url)) {
if (_disk != null) {
2021-04-11 19:50:39 +08:00
string name = Path.GetFileName (url);
VFile file = _disk.GetFile (name, string.Empty);
2021-04-08 20:09:59 +08:00
if (file != null) {
return AssetBundle.LoadFromFile (_disk.name, 0, (ulong)file.offset);
}
}
}
return AssetBundle.LoadFromFile (url);
}
public static AssetBundleCreateRequest LoadAssetBundleFromFileAsync (string url)
{
if (!File.Exists (url)) {
if (_disk != null) {
2021-04-11 19:50:39 +08:00
string name = Path.GetFileName (url);
VFile file = _disk.GetFile (name, string.Empty);
2021-04-08 20:09:59 +08:00
if (file != null) {
return AssetBundle.LoadFromFileAsync (_disk.name, 0, (ulong)file.offset);
}
}
}
return AssetBundle.LoadFromFileAsync (url);
}
public static void BuildVersions (string outputPath, string[] bundles, int version)
{
2021-04-11 19:50:39 +08:00
string path = outputPath + "/" + Filename;
2021-04-08 20:09:59 +08:00
if (File.Exists (path)) {
File.Delete (path);
}
2021-04-11 19:50:39 +08:00
string dataPath = outputPath + "/" + Dataname;
2021-04-08 20:09:59 +08:00
if (File.Exists (dataPath)) {
File.Delete (dataPath);
}
2021-04-11 19:50:39 +08:00
VDisk disk = new VDisk ();
foreach (string file in bundles) {
using (FileStream fs = File.OpenRead (outputPath + "/" + file)) {
2021-04-08 20:09:59 +08:00
disk.AddFile (file, fs.Length, Utilitys.GetCRC32Hash (fs));
}
}
disk.name = dataPath;
disk.Save ();
2021-04-11 19:50:39 +08:00
using (FileStream stream = File.OpenWrite (path)) {
BinaryWriter writer = new BinaryWriter (stream);
2021-04-08 20:09:59 +08:00
writer.Write (version);
writer.Write (disk.files.Count + 1);
2021-04-11 19:50:39 +08:00
using (FileStream fs = File.OpenRead (dataPath)) {
VFile file = new VFile { name = Dataname, len = fs.Length, hash = Utilitys.GetCRC32Hash (fs) };
2021-04-08 20:09:59 +08:00
file.Serialize (writer);
}
2021-04-11 19:50:39 +08:00
foreach (VFile file in disk.files) {
2021-04-08 20:09:59 +08:00
file.Serialize (writer);
}
}
}
public static int LoadVersion (string filename)
{
if (!File.Exists (filename))
return -1;
try
{
2021-04-11 19:50:39 +08:00
using (FileStream stream = File.OpenRead (filename)) {
BinaryReader reader = new BinaryReader (stream);
2021-04-08 20:09:59 +08:00
if (reader.BaseStream.Position != reader.BaseStream.Length)
{
return reader.ReadInt32();
}
return -1;
}
}
catch (Exception e)
{
Debug.LogException(e);
return -1;
}
}
public static List<VFile> LoadVersions (string filename, bool update = false)
{
2021-04-11 19:50:39 +08:00
string rootDir = Path.GetDirectoryName(filename);
2021-04-08 20:09:59 +08:00
var data = update ? _updateData : _baseData;
data.Clear ();
2021-04-11 19:50:39 +08:00
using (FileStream stream = File.OpenRead (filename)) {
BinaryReader reader = new BinaryReader (stream);
2021-04-08 20:09:59 +08:00
var list = new List<VFile> ();
2021-04-11 19:50:39 +08:00
int ver = reader.ReadInt32 ();
2021-04-08 20:09:59 +08:00
Debug.Log ($"LoadVersions:{ver} \n{filename}");
2021-04-11 19:50:39 +08:00
int count = reader.ReadInt32 ();
for (int i = 0; i < count; i++) {
VFile version = new VFile ();
2021-04-08 20:09:59 +08:00
version.Deserialize (reader);
list.Add (version);
data [version.name] = version;
2021-04-11 19:50:39 +08:00
string dir = string.Format("{0}/{1}", rootDir, Path.GetDirectoryName(version.name));
2021-04-08 20:09:59 +08:00
if (! Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
}
return list;
}
}
public static void UpdateDisk(string savePath, List<VFile> newFiles)
{
var saveFiles = new List<VFile> ();
var files = _disk.files;
2021-04-11 19:50:39 +08:00
foreach (VFile file in files) {
2021-04-08 20:09:59 +08:00
if (_updateData.ContainsKey (file.name)) {
saveFiles.Add (file);
}
}
_disk.Update(savePath, newFiles, saveFiles);
}
public static bool LoadDisk (string filename)
{
return _disk.Load (filename);
}
public static bool IsNew (string path, long len, string hash)
{
VFile file;
2021-04-11 19:50:39 +08:00
string key = Path.GetFileName (path);
2021-04-08 20:09:59 +08:00
if (_baseData.TryGetValue (key, out file)) {
if (key.Equals (Dataname) ||
file.len == len && file.hash.Equals (hash, StringComparison.OrdinalIgnoreCase)) {
return false;
}
}
if (_disk.Exists ()) {
2021-04-11 19:50:39 +08:00
VFile vdf = _disk.GetFile (path, hash);
2021-04-08 20:09:59 +08:00
if (vdf != null && vdf.len == len && vdf.hash.Equals (hash, StringComparison.OrdinalIgnoreCase)) {
return false;
}
}
if (!File.Exists (path)) {
return true;
}
2021-04-11 19:50:39 +08:00
using (FileStream stream = File.OpenRead (path)) {
2021-04-08 20:09:59 +08:00
if (stream.Length != len) {
return true;
}
if (verifyBy != VerifyBy.Hash)
return false;
return !Utilitys.GetCRC32Hash (stream).Equals (hash, StringComparison.OrdinalIgnoreCase);
}
}
}
}