237 lines
9.0 KiB
C#
237 lines
9.0 KiB
C#
using CaoCao.XAsset;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using UnityEditor;
|
||
using UnityEditor.Build;
|
||
using UnityEditor.Build.Reporting;
|
||
using UnityEngine;
|
||
|
||
namespace CaoCao.Editor
|
||
{
|
||
public class BuildPlayerAssets : IPreprocessBuildWithReport, IPostprocessBuildWithReport
|
||
{
|
||
//打包后自动调用
|
||
public void OnPostprocessBuild(BuildReport report)
|
||
{
|
||
var dataPath = $"{Application.streamingAssetsPath}/{Assets.Bundles}";
|
||
if (!Directory.Exists(dataPath))
|
||
return;
|
||
|
||
FileUtil.DeleteFileOrDirectory(dataPath);
|
||
FileUtil.DeleteFileOrDirectory(dataPath + ".meta");
|
||
|
||
if (Directory.GetFiles(Application.streamingAssetsPath).Length != 0)
|
||
return;
|
||
|
||
FileUtil.DeleteFileOrDirectory(Application.streamingAssetsPath);
|
||
FileUtil.DeleteFileOrDirectory(Application.streamingAssetsPath + ".meta");
|
||
}
|
||
|
||
public int callbackOrder { get; }
|
||
|
||
//打包前自动调用
|
||
public void OnPreprocessBuild(BuildReport report)
|
||
{
|
||
StartNew();
|
||
}
|
||
|
||
public static Action<BuildPlayerAssets> CustomBuilder { get; set; }
|
||
private Versions versions { get; set; }
|
||
|
||
public static void StartNew(Versions versions = null)
|
||
{
|
||
new BuildPlayerAssets {versions = versions}.Start();
|
||
}
|
||
|
||
private void Start()
|
||
{
|
||
//从BuildCache中读取versions.json
|
||
if (versions == null)
|
||
versions = Settings.GetDefaultVersions();
|
||
|
||
if (CustomBuilder != null)
|
||
{
|
||
CustomBuilder.Invoke(this);
|
||
return;
|
||
}
|
||
|
||
var dataPath = $"{Application.streamingAssetsPath}/{Assets.Bundles}";
|
||
var settings = Settings.GetDefaultSettings();
|
||
if (Settings.Platform == Platform.iOS)
|
||
{
|
||
// iOS 下散文件 IO 效率更高
|
||
settings.packPlayerAssets = false;
|
||
}
|
||
|
||
var playerAssets = settings.GetPlayerAssets();
|
||
|
||
if (Directory.Exists(dataPath))
|
||
{
|
||
FileUtil.DeleteFileOrDirectory(dataPath);
|
||
FileUtil.DeleteFileOrDirectory($"{dataPath}.meta");
|
||
}
|
||
|
||
//根据versions获取到设置为交付模式为Install Time的bundle包
|
||
var bundles = Builder.GetBundlesInBuild(settings, versions);
|
||
if (bundles.Length > 0)
|
||
CopyBundles(bundles, playerAssets, settings.bundle.encryption ? XAsset.Utility.WriteOffset : 0);
|
||
|
||
// 保存版本文件
|
||
foreach (var version in versions.data)
|
||
{
|
||
////分包版本文件不加入包中
|
||
//if (version.subPackage)
|
||
// continue;
|
||
|
||
var from = Settings.GetDataPath(version.file);
|
||
var to = Assets.GetPlayerDataPath(version.file);
|
||
XAsset.Utility.CreateDirectoryIfNecessary(to);
|
||
File.Copy(from, to, true);
|
||
}
|
||
|
||
// WebGL 不需要搞 PlayerAssets。
|
||
if (Settings.Platform == Platform.WebGL)
|
||
playerAssets.data.Clear();
|
||
|
||
var json = JsonUtility.ToJson(playerAssets);
|
||
// 将playerassets.json文件写入streamingAssetsPath文件夹
|
||
var path = Assets.GetPlayerDataPath(PlayerAssets.Filename);
|
||
XAsset.Utility.CreateDirectoryIfNecessary(path);
|
||
File.WriteAllText(path, json);
|
||
// 将version.json文件写入streamingAssetsPath文件夹
|
||
path = Assets.GetPlayerDataPath(Versions.Filename);
|
||
XAsset.Utility.CreateDirectoryIfNecessary(path);
|
||
versions.Save(path);
|
||
}
|
||
|
||
//TODO:带修改,加密
|
||
private static void CopyBundles(IEnumerable<ManifestBundle> bundles, PlayerAssets playerAssets,
|
||
ulong offset = 0)
|
||
{
|
||
bool bXor = false;
|
||
if (!playerAssets.packed)
|
||
{
|
||
foreach (var bundle in bundles)
|
||
{
|
||
bXor = false;
|
||
var from = Settings.GetDataPath(bundle.file);
|
||
var to = Assets.GetPlayerDataPath(bundle.file);
|
||
var file = new FileInfo(from);
|
||
if (file.Exists)
|
||
{
|
||
#if ENABLE_NEWENCRY //@取消贴图加密
|
||
//不加密
|
||
XAsset.Utility.CreateDirectoryIfNecessary(to);
|
||
file.CopyTo(to, true);
|
||
playerAssets.data.Add(PackedAsset.Create(bundle, offset));
|
||
#else
|
||
if (bundle.file.Contains("1_texture"))
|
||
bXor = true;
|
||
|
||
if (!bXor)
|
||
{
|
||
XAsset.Utility.CreateDirectoryIfNecessary(to);
|
||
file.CopyTo(to, true);
|
||
playerAssets.data.Add(PackedAsset.Create(bundle, offset));
|
||
}
|
||
else
|
||
{
|
||
//把以加密的数据解密回来
|
||
using (var writer = new BinaryWriter(File.OpenWrite(to)))
|
||
{
|
||
var stream = File.OpenRead(from);
|
||
using var reader = new BinaryReader(stream);
|
||
string hash = reader.ReadString();
|
||
byte[] hashBytes = System.Text.Encoding.UTF8.GetBytes(hash);
|
||
//读取剩余数据
|
||
ulong len = (ulong)stream.Length - offset;
|
||
var bytes = reader.ReadBytes((int)len);
|
||
XAsset.Utility.GetSelfXorBytes(bytes, hashBytes);
|
||
writer.Write(hash);
|
||
writer.Write(bytes);
|
||
reader.Close();
|
||
}
|
||
}
|
||
#endif
|
||
|
||
|
||
}
|
||
else
|
||
{
|
||
XAsset.Logger.E($"File not found: {from}");
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
var path = Assets.GetPlayerDataPath(playerAssets.GetAssetName());
|
||
if (File.Exists(path))
|
||
{
|
||
File.Delete(path);
|
||
}
|
||
|
||
XAsset.Utility.CreateDirectoryIfNecessary(path);
|
||
|
||
using (var writer = new BinaryWriter(File.OpenWrite(path)))
|
||
{
|
||
foreach (var bundle in bundles)
|
||
{
|
||
bXor = false;
|
||
var from = Settings.GetDataPath(bundle.file);
|
||
var file = new FileInfo(from);
|
||
if (file.Exists)
|
||
{
|
||
|
||
|
||
#if ENABLE_NEWENCRY //@取消贴图加密
|
||
playerAssets.data.Add(PackedAsset.Create(bundle, (ulong)writer.BaseStream.Position + offset));
|
||
writer.Write(File.ReadAllBytes(from));
|
||
#else
|
||
if (bundle.file.Contains("1_texture"))
|
||
bXor = true;
|
||
if (!bXor)
|
||
{
|
||
playerAssets.data.Add(PackedAsset.Create(bundle, (ulong)writer.BaseStream.Position + offset));
|
||
writer.Write(File.ReadAllBytes(from));
|
||
}
|
||
else
|
||
{
|
||
// 安卓下,StreamingAssets内文件不支持C#的IO
|
||
// 所以把以加密的数据解密回来
|
||
|
||
playerAssets.data.Add(PackedAsset.Create(bundle, (ulong)writer.BaseStream.Position + offset));
|
||
var stream = File.OpenRead(from);
|
||
using var reader = new BinaryReader(stream);
|
||
string hash = reader.ReadString();
|
||
byte[] hashBytes = System.Text.Encoding.UTF8.GetBytes(hash);
|
||
|
||
//读取剩余数据
|
||
ulong len = (ulong)stream.Length - offset;
|
||
var bytes = reader.ReadBytes((int)len);
|
||
|
||
XAsset.Utility.GetSelfXorBytes(bytes, hashBytes);
|
||
writer.Write(hash);
|
||
writer.Write(bytes);
|
||
|
||
reader.Close();
|
||
}
|
||
#endif
|
||
}
|
||
else
|
||
{
|
||
XAsset.Logger.E($"File not found: {from}");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
#if ENABLE_NEWENCRY //@取消贴图加密
|
||
Debug.Log("是“取消贴图加密”模式");
|
||
#else
|
||
Debug.Log("旧模式,非“取消贴图加密”模式");
|
||
#endif
|
||
}
|
||
}
|
||
} |