TheInitialProject/Assets/CaoCao/Scripts/Editor/XAsset/Build/Steps/BuildPlayerAssets.cs
2024-10-23 16:59:02 +08:00

237 lines
9.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}
}
}