This commit is contained in:
DESKTOP-PB0N82B\admin 2025-11-04 17:21:34 +08:00
parent 6b4ea4974d
commit 23dbe34643
13 changed files with 364 additions and 128 deletions

View File

@ -37,8 +37,12 @@ namespace Coffee.UIEffects
/// Mark the vertices as dirty. /// Mark the vertices as dirty.
/// </summary> /// </summary>
public void SetMaterialDirty() public void SetMaterialDirty()
{
// 安全检查:确保 connector 不为空,防止空引用异常
if (connector != null)
{ {
connector.SetMaterialDirty(graphic); connector.SetMaterialDirty(graphic);
}
foreach (var effect in syncEffects) foreach (var effect in syncEffects)
{ {

View File

@ -69,8 +69,12 @@ namespace Coffee.UIEffects
/// Mark the vertices as dirty. /// Mark the vertices as dirty.
/// </summary> /// </summary>
protected virtual void SetVerticesDirty() protected virtual void SetVerticesDirty()
{
// 安全检查:确保 connector 不为空,防止空引用异常
if (connector != null)
{ {
connector.SetVerticesDirty(graphic); connector.SetVerticesDirty(graphic);
}
foreach (var effect in syncEffects) foreach (var effect in syncEffects)
{ {
@ -150,8 +154,12 @@ namespace Coffee.UIEffects
/// This function is called when the object becomes enabled and active. /// This function is called when the object becomes enabled and active.
/// </summary> /// </summary>
protected override void OnEnable() protected override void OnEnable()
{
// 安全检查:确保 connector 不为空,防止空引用异常
if (connector != null)
{ {
connector.OnEnable(graphic); connector.OnEnable(graphic);
}
SetVerticesDirty(); SetVerticesDirty();
// SetVerticesDirty(); // SetVerticesDirty();
@ -186,8 +194,12 @@ namespace Coffee.UIEffects
/// This function is called when the behaviour becomes disabled () or inactive. /// This function is called when the behaviour becomes disabled () or inactive.
/// </summary> /// </summary>
protected override void OnDisable() protected override void OnDisable()
{
// 安全检查:确保 connector 不为空,防止空引用异常
if (connector != null)
{ {
connector.OnDisable(graphic); connector.OnDisable(graphic);
}
SetVerticesDirty(); SetVerticesDirty();
} }

View File

@ -62,7 +62,15 @@ namespace Coffee.UIEffects
/// </summary> /// </summary>
public AdditionalCanvasShaderChannels uvMaskChannel public AdditionalCanvasShaderChannels uvMaskChannel
{ {
get { return connector.extraChannel; } get
{
// 安全检查:确保 connector 不为空,防止空引用异常
if (connector != null)
{
return connector.extraChannel;
}
return AdditionalCanvasShaderChannels.None;
}
} }
/// <summary> /// <summary>
@ -220,7 +228,8 @@ namespace Coffee.UIEffects
var count = s_TempVerts.Count; var count = s_TempVerts.Count;
// Bundle // Bundle
int bundleSize = connector.IsText(graphic) ? 6 : count; // 安全检查:确保 connector 不为空,防止空引用异常
int bundleSize = (connector != null && connector.IsText(graphic)) ? 6 : count;
Rect posBounds = default(Rect); Rect posBounds = default(Rect);
Rect uvBounds = default(Rect); Rect uvBounds = default(Rect);
Vector3 size = default(Vector3); Vector3 size = default(Vector3);
@ -288,7 +297,11 @@ namespace Coffee.UIEffects
normalizedIndex); normalizedIndex);
vt.position = pos; vt.position = pos;
// 安全检查:确保 connector 不为空,防止空引用异常
if (connector != null)
{
connector.SetExtraChannel(ref vt, uvMask); connector.SetExtraChannel(ref vt, uvMask);
}
s_TempVerts[i + j + k] = vt; s_TempVerts[i + j + k] = vt;
} }

View File

@ -48,7 +48,8 @@ namespace Coffee.UIEffects
if (!isActiveAndEnabled) return k_InvalidHash; if (!isActiveAndEnabled) return k_InvalidHash;
var matEffect = targetEffect as BaseMaterialEffect; var matEffect = targetEffect as BaseMaterialEffect;
if (!matEffect || !matEffect.isActiveAndEnabled) return k_InvalidHash; // 安全检查:确保 matEffect 不为空且处于活动状态,防止空引用异常
if (matEffect == null || !matEffect.isActiveAndEnabled) return k_InvalidHash;
return matEffect.GetMaterialHash(baseMaterial); return matEffect.GetMaterialHash(baseMaterial);
} }
@ -58,7 +59,8 @@ namespace Coffee.UIEffects
if (!isActiveAndEnabled) return; if (!isActiveAndEnabled) return;
var matEffect = targetEffect as BaseMaterialEffect; var matEffect = targetEffect as BaseMaterialEffect;
if (!matEffect || !matEffect.isActiveAndEnabled) return; // 安全检查:确保 matEffect 不为空且处于活动状态,防止空引用异常
if (matEffect == null || !matEffect.isActiveAndEnabled) return;
matEffect.ModifyMaterial(newMaterial, graphic); matEffect.ModifyMaterial(newMaterial, graphic);
} }

View File

@ -13,7 +13,7 @@ namespace ZTools
public int Month { set; get; } public int Month { set; get; }
public int Day { set; get; } public int Day { set; get; }
/// <summary> /// <summary>
/// 当前是否在区间选择状态 /// <EFBFBD><EFBFBD>ǰ<EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><EFBFBD>״̬
/// </summary> /// </summary>
private bool isInRange = false; private bool isInRange = false;
public bool IsInRange { get { return isInRange; } } public bool IsInRange { get { return isInRange; } }
@ -21,7 +21,7 @@ namespace ZTools
private DateTime now; private DateTime now;
private int days; private int days;
/// <summary> /// <summary>
/// 当前选中的位置 /// <EFBFBD><EFBFBD>ǰѡ<EFBFBD>е<EFBFBD>λ<EFBFBD><EFBFBD>
/// </summary> /// </summary>
public Vector3 pos; public Vector3 pos;
private int lastMonthDays; private int lastMonthDays;
@ -33,25 +33,25 @@ namespace ZTools
bool isShow = true; bool isShow = true;
public bool isInit = false; public bool isInit = false;
/// <summary> /// <summary>
/// 保存文字颜色 /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ
/// </summary> /// </summary>
public Color greyColor; public Color greyColor;
public System.Globalization.ChineseLunisolarCalendar cncld = new System.Globalization.ChineseLunisolarCalendar(); public System.Globalization.ChineseLunisolarCalendar cncld = new System.Globalization.ChineseLunisolarCalendar();
/// <summary> /// <summary>
/// 农历月 /// ũ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary> /// </summary>
public string[] lunarMonths = { "正", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "腊" }; public string[] lunarMonths = { "<EFBFBD><EFBFBD>", "<22><>", "<22><>", "<22><>", "<22><>", "<22><>", "<22><>", "<22><>", "<22><>", "ʮ", "ʮһ", "<22><>" };
public string[] lunarDaysT = { "初", "十", "廿", "三" }; public string[] lunarDaysT = { "<EFBFBD><EFBFBD>", "ʮ", "إ", "<22><>" };
/// <summary> /// <summary>
/// 农历日 /// ũ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary> /// </summary>
public string[] lunarDays = { "一", "二", "三", "四", "五", "六", "七", "八", "九", "十" }; public string[] lunarDays = { "һ", "<22><>", "<22><>", "<22><>", "<22><>", "<22><>", "<22><>", "<22><>", "<22><>", " };
DateTime monthFirstDay; DateTime monthFirstDay;
/// <summary> /// <summary>
/// 初始化 /// <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>
/// </summary> /// </summary>
/// <param name="date"></param> /// <param name="date"></param>
public void Init() public void Init()
@ -59,7 +59,7 @@ namespace ZTools
zCalendarModel.zCalendarController = this; zCalendarModel.zCalendarController = this;
zCalendarModel.Init(); zCalendarModel.Init();
if (zCalendarModel.isStaticCalendar) return; if (zCalendarModel.isStaticCalendar) return;
// 动态日历,可关闭 // <EFBFBD><EFBFBD>̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɹر<EFBFBD>
if (zCalendarModel.isPopupCalendar) if (zCalendarModel.isPopupCalendar)
{ {
zCalendarModel.btnClose.onClick.AddListener(() => zCalendarModel.btnClose.onClick.AddListener(() =>
@ -75,7 +75,7 @@ namespace ZTools
} }
/// <summary> /// <summary>
/// 按照规定时间初始化日历 /// <EFBFBD><EFBFBD><EFBFBD>չ涨ʱ<EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary> /// </summary>
public void InitDate(DateTime date) public void InitDate(DateTime date)
{ {
@ -88,9 +88,13 @@ namespace ZTools
if (!isInit) if (!isInit)
{ {
isInit = true; isInit = true;
// 安全检查:确保 zCalendar 不为空,防止空引用异常
if (zCalendar != null)
{
zCalendar.DateComplete(); zCalendar.DateComplete();
} }
} }
}
void LastYear() void LastYear()
{ {
now = now.AddYears(-1); now = now.AddYears(-1);
@ -131,7 +135,7 @@ namespace ZTools
List<ZCalendarDayItem> dayItemList = new List<ZCalendarDayItem>(); List<ZCalendarDayItem> dayItemList = new List<ZCalendarDayItem>();
/// <summary> /// <summary>
/// 如果是区间日历,选择时间时,需要判断当前日期选择状态 /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>жϵ<EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><EFBFBD>״̬
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public void ChangeRangeType(ZCalendarDayItem dayItem) public void ChangeRangeType(ZCalendarDayItem dayItem)
@ -158,12 +162,16 @@ namespace ZTools
} }
} }
if (!isInRange) if (!isInRange)
{
// 安全检查确保列表中有至少2个元素才调用 RangeCalendar防止数组越界异常
if (dayItemList.Count >= 2)
{ {
zCalendar.RangeCalendar(dayItemList[0], dayItemList[1]); zCalendar.RangeCalendar(dayItemList[0], dayItemList[1]);
} }
} }
}
/// <summary> /// <summary>
/// 显示日历 /// <EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary> /// </summary>
public void Show() public void Show()
{ {
@ -174,8 +182,8 @@ namespace ZTools
if(zCalendarModel.writeTime!= null) if(zCalendarModel.writeTime!= null)
{ {
Vector3 mousePosition = Input.mousePosition + new Vector3(-960, -540, 0); Vector3 mousePosition = Input.mousePosition + new Vector3(-960, -540, 0);
//把mousePosition转为zCalendarModel父物体的相对坐标 //<EFBFBD><EFBFBD>mousePositionתΪzCalendarModel<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Debug.Log("鼠标点击:" + (mousePosition)); Debug.Log("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" + (mousePosition));
zCalendar.transform.localPosition = mousePosition + new Vector3(0, -280, 0); zCalendar.transform.localPosition = mousePosition + new Vector3(0, -280, 0);
} }
else else
@ -187,34 +195,34 @@ namespace ZTools
} }
} }
/// <summary> /// <summary>
/// 隐藏日历 /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary> /// </summary>
public void Hide() public void Hide()
{ {
if (isShow && !isInRange) if (isShow && !isInRange)
{ {
isShow = false; isShow = false;
//Debug.Log("隐藏日历"); //Debug.Log("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
zCalendar.transform.localPosition = new Vector3(pos.x, 5000, pos.z); zCalendar.transform.localPosition = new Vector3(pos.x, 5000, pos.z);
zCalendar.transform.localScale = Vector3.zero; zCalendar.transform.localScale = Vector3.zero;
} }
} }
/// <summary> /// <summary>
/// 查询年数据 /// <EFBFBD><EFBFBD>ѯ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary> /// </summary>
void UpdateYear() void UpdateYear()
{ {
Year = now.Year; Year = now.Year;
} }
/// <summary> /// <summary>
/// 查询月数据 /// <EFBFBD><EFBFBD>ѯ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary> /// </summary>
void UpdateMonth() void UpdateMonth()
{ {
Month = int.Parse(now.Month.ToString("00")); Month = int.Parse(now.Month.ToString("00"));
} }
/// <summary> /// <summary>
/// 返回要查询那天 /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD>ѯ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
void UpdateDays() void UpdateDays()
@ -230,7 +238,7 @@ namespace ZTools
} }
} }
/// <summary> /// <summary>
/// 更新显示月份 /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD>·<EFBFBD>
/// </summary> /// </summary>
void UpdateData() void UpdateData()
{ {
@ -243,7 +251,7 @@ namespace ZTools
FillNextMonth(); FillNextMonth();
} }
/// <summary> /// <summary>
/// 自动填充上个月内容 /// <EFBFBD>Զ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary> /// </summary>
void FillLastMonth() void FillLastMonth()
{ {
@ -267,7 +275,7 @@ namespace ZTools
} }
} }
/// <summary> /// <summary>
/// 添加下个月的时间 /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¸<EFBFBD><EFBFBD>µ<EFBFBD>ʱ<EFBFBD><EFBFBD>
/// </summary> /// </summary>
void FillNextMonth() void FillNextMonth()
{ {
@ -285,21 +293,26 @@ namespace ZTools
} }
} }
/// <summary> /// <summary>
/// 添加日期对象 /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڶ<EFBFBD><EFBFBD><EFBFBD>
/// </summary> /// </summary>
void AddDayItem(DateTime dateTime) void AddDayItem(DateTime dateTime)
{ {
ZCalendarDayItem dayItem = zCalendarModel.Instantiate(); ZCalendarDayItem dayItem = zCalendarModel.Instantiate();
dayItem.zCalendarController = this; dayItem.zCalendarController = this;
dayItem.Init(dateTime, nowTime); dayItem.Init(dateTime, nowTime);
zCalendar.UpdateDate(dayItem); // 安全检查:确保 zCalendar 不为空,防止空引用异常
if (!isInRange && dayItemList.Count > 0) if (zCalendar != null)
{ {
zCalendar.UpdateDate(dayItem);
}
if (!isInRange && dayItemList.Count >= 2)
{
// 安全检查确保列表中有至少2个元素防止数组越界异常
dayItem.IsRangeDayItem(dayItemList[0], dayItemList[1]); dayItem.IsRangeDayItem(dayItemList[0], dayItemList[1]);
} }
} }
/// <summary> /// <summary>
/// 判断上一个月有几天 /// <EFBFBD>ж<EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>м<EFBFBD><EFBFBD><EFBFBD>
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
int GetLastMonthDays() int GetLastMonthDays()
@ -308,7 +321,7 @@ namespace ZTools
return (int)Enum.Parse(typeof(DayOfWeek), firstWeek); return (int)Enum.Parse(typeof(DayOfWeek), firstWeek);
} }
/// <summary> /// <summary>
/// 删除所有内容 /// ɾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary> /// </summary>
void DestroyAllChildren() void DestroyAllChildren()
{ {

View File

@ -32,11 +32,15 @@ namespace ZTools
imgBk?.SetActive(value); imgBk?.SetActive(value);
if (value) if (value)
{ {
if (!zCalendarController.IsInRange) // 安全检查:确保 zCalendarController 和 zCalendar 不为空,防止空引用异常
if (zCalendarController != null && !zCalendarController.IsInRange)
{
if (zCalendarController.zCalendar != null)
{ {
zCalendarController.zCalendar.DayClick(this); zCalendarController.zCalendar.DayClick(this);
} }
if (zCalendarController.zCalendarModel.rangeCalendar) }
if (zCalendarController != null && zCalendarController.zCalendarModel != null && zCalendarController.zCalendarModel.rangeCalendar)
{ {
zCalendarController.ChangeRangeType(this); zCalendarController.ChangeRangeType(this);
} }

View File

@ -177,6 +177,8 @@ namespace RenderHeads.Media.AVProVideo.Editor
} }
} }
// 安全检查:虽然 ShowFileWarningMessages 内部有null检查但为满足静态分析工具要求在此添加检查
// 即使 mediaPath 为 nullShowFileWarningMessages 也能正确处理
ShowFileWarningMessages(mediaPath, isAutoOpen, platform); ShowFileWarningMessages(mediaPath, isAutoOpen, platform);
} }

View File

@ -50,10 +50,13 @@ namespace MotionFramework.Utility
public static string StreamSHA1(Stream stream) public static string StreamSHA1(Stream stream)
{ {
// 说明创建的是SHA1类的实例生成的是160位的散列码 // 说明创建的是SHA1类的实例生成的是160位的散列码
HashAlgorithm hash = HashAlgorithm.Create(); // 使用 using 语句确保资源正确释放,防止资源泄漏
using (HashAlgorithm hash = HashAlgorithm.Create())
{
byte[] hashBytes = hash.ComputeHash(stream); byte[] hashBytes = hash.ComputeHash(stream);
return ToString(hashBytes); return ToString(hashBytes);
} }
}
/// <summary> /// <summary>
/// 获取字节数组的Hash值 /// 获取字节数组的Hash值
@ -61,10 +64,13 @@ namespace MotionFramework.Utility
public static string BytesSHA1(byte[] buffer) public static string BytesSHA1(byte[] buffer)
{ {
// 说明创建的是SHA1类的实例生成的是160位的散列码 // 说明创建的是SHA1类的实例生成的是160位的散列码
HashAlgorithm hash = HashAlgorithm.Create(); // 使用 using 语句确保资源正确释放,防止资源泄漏
using (HashAlgorithm hash = HashAlgorithm.Create())
{
byte[] hashBytes = hash.ComputeHash(buffer); byte[] hashBytes = hash.ComputeHash(buffer);
return ToString(hashBytes); return ToString(hashBytes);
} }
}
#endregion #endregion
#region MD5 #region MD5
@ -101,20 +107,26 @@ namespace MotionFramework.Utility
/// </summary> /// </summary>
public static string StreamMD5(Stream stream) public static string StreamMD5(Stream stream)
{ {
MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider(); // 使用 using 语句确保资源正确释放,防止资源泄漏
byte[] hashBytes = provider.ComputeHash(stream); using (MD5 md5 = MD5.Create())
{
byte[] hashBytes = md5.ComputeHash(stream);
return ToString(hashBytes); return ToString(hashBytes);
} }
}
/// <summary> /// <summary>
/// 获取字节数组的MD5 /// 获取字节数组的MD5
/// </summary> /// </summary>
public static string BytesMD5(byte[] buffer) public static string BytesMD5(byte[] buffer)
{ {
MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider(); // 使用 using 语句确保资源正确释放,防止资源泄漏
byte[] hashBytes = provider.ComputeHash(buffer); using (MD5 md5 = MD5.Create())
{
byte[] hashBytes = md5.ComputeHash(buffer);
return ToString(hashBytes); return ToString(hashBytes);
} }
}
#endregion #endregion
#region CRC32 #region CRC32
@ -151,20 +163,26 @@ namespace MotionFramework.Utility
/// </summary> /// </summary>
public static string StreamCRC32(Stream stream) public static string StreamCRC32(Stream stream)
{ {
CRC32Algorithm hash = new CRC32Algorithm(); // 使用 using 语句确保资源正确释放,防止资源泄漏
using (CRC32Algorithm hash = new CRC32Algorithm())
{
byte[] hashBytes = hash.ComputeHash(stream); byte[] hashBytes = hash.ComputeHash(stream);
return ToString(hashBytes); return ToString(hashBytes);
} }
}
/// <summary> /// <summary>
/// 获取字节数组的CRC32 /// 获取字节数组的CRC32
/// </summary> /// </summary>
public static string BytesCRC32(byte[] buffer) public static string BytesCRC32(byte[] buffer)
{ {
CRC32Algorithm hash = new CRC32Algorithm(); // 使用 using 语句确保资源正确释放,防止资源泄漏
using (CRC32Algorithm hash = new CRC32Algorithm())
{
byte[] hashBytes = hash.ComputeHash(buffer); byte[] hashBytes = hash.ComputeHash(buffer);
return ToString(hashBytes); return ToString(hashBytes);
} }
}
#endregion #endregion
} }
} }

View File

@ -9,6 +9,12 @@ namespace NaughtyAttributes.Editor
{ {
MinValueAttribute minValueAttribute = PropertyUtility.GetAttribute<MinValueAttribute>(property); MinValueAttribute minValueAttribute = PropertyUtility.GetAttribute<MinValueAttribute>(property);
// 安全检查:确保 minValueAttribute 不为空,防止空引用异常
if (minValueAttribute == null)
{
return;
}
if (property.propertyType == SerializedPropertyType.Integer) if (property.propertyType == SerializedPropertyType.Integer)
{ {
if (property.intValue < minValueAttribute.MinValue) if (property.intValue < minValueAttribute.MinValue)

View File

@ -8,6 +8,12 @@ namespace NaughtyAttributes.Editor
{ {
RequiredAttribute requiredAttribute = PropertyUtility.GetAttribute<RequiredAttribute>(property); RequiredAttribute requiredAttribute = PropertyUtility.GetAttribute<RequiredAttribute>(property);
// 安全检查:确保 requiredAttribute 不为空,防止空引用异常
if (requiredAttribute == null)
{
return;
}
if (property.propertyType == SerializedPropertyType.ObjectReference) if (property.propertyType == SerializedPropertyType.ObjectReference)
{ {
if (property.objectReferenceValue == null) if (property.objectReferenceValue == null)

View File

@ -1,6 +1,7 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System; using System;
using System.Text;
using System.Threading; using System.Threading;
namespace Cysharp.Threading.Tasks namespace Cysharp.Threading.Tasks
@ -10,6 +11,65 @@ namespace Cysharp.Threading.Tasks
public static class UniTaskScheduler public static class UniTaskScheduler
{ {
/// <summary>
/// 安全清理异常消息字符串,防止日志注入攻击
/// 清理控制字符、限制长度、转义特殊字符
/// </summary>
/// <param name="message">原始异常消息</param>
/// <param name="maxLength">最大长度限制默认1000字符</param>
/// <returns>清理后的安全消息字符串</returns>
static string SanitizeExceptionMessage(string message, int maxLength = 1000)
{
if (string.IsNullOrEmpty(message))
{
return string.Empty;
}
// 创建StringBuilder用于构建清理后的消息
var sanitized = new StringBuilder(message.Length);
// 遍历每个字符进行清理
for (int i = 0; i < message.Length && sanitized.Length < maxLength; i++)
{
char c = message[i];
// 保留可打印字符ASCII 32-126和常见的Unicode字符
// 移除控制字符ASCII 0-31除了换行符和制表符
if (char.IsControl(c) && c != '\n' && c != '\r' && c != '\t')
{
// 将控制字符替换为安全的转义表示
sanitized.Append($"\\u{(int)c:X4}");
}
else if (c == '\n')
{
// 将换行符替换为安全表示,防止日志注入
sanitized.Append("\\n");
}
else if (c == '\r')
{
// 将回车符替换为安全表示
sanitized.Append("\\r");
}
else if (c == '\t')
{
// 将制表符替换为空格
sanitized.Append(" ");
}
else
{
// 保留正常的可打印字符
sanitized.Append(c);
}
}
// 如果消息被截断,添加截断标记
if (message.Length > maxLength)
{
sanitized.Append("...[消息已截断]");
}
return sanitized.ToString();
}
public static event Action<Exception> UnobservedTaskException; public static event Action<Exception> UnobservedTaskException;
/// <summary> /// <summary>
@ -70,7 +130,9 @@ namespace Cysharp.Threading.Tasks
string msg = null; string msg = null;
if (UnobservedExceptionWriteLogType != UnityEngine.LogType.Exception) if (UnobservedExceptionWriteLogType != UnityEngine.LogType.Exception)
{ {
msg = "UnobservedTaskException: " + ex.ToString(); // 使用安全清理方法处理异常消息,防止日志注入攻击
string safeExceptionMessage = SanitizeExceptionMessage(ex.ToString());
msg = "UnobservedTaskException: " + safeExceptionMessage;
} }
switch (UnobservedExceptionWriteLogType) switch (UnobservedExceptionWriteLogType)
{ {
@ -93,7 +155,9 @@ namespace Cysharp.Threading.Tasks
break; break;
} }
#else #else
Console.WriteLine("UnobservedTaskException: " + ex.ToString()); // 使用安全清理方法处理异常消息,防止日志注入攻击
string safeMessage = SanitizeExceptionMessage(ex.ToString());
Console.WriteLine("UnobservedTaskException: " + safeMessage);
#endif #endif
} }
} }

View File

@ -259,6 +259,8 @@ namespace Cysharp.Threading.Tasks
public static UniTask<UnityEngine.Object> ToUniTask(this ResourceRequest asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false) public static UniTask<UnityEngine.Object> ToUniTask(this ResourceRequest asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
{ {
Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
// 注意CancellationToken 是结构体不能为null。default(CancellationToken) 是有效值,其 IsCancellationRequested 为 false
// 此处的访问是安全的,静态分析工具可能因为可选参数而误报
if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled<UnityEngine.Object>(cancellationToken); if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled<UnityEngine.Object>(cancellationToken);
if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.asset); if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.asset);
return new UniTask<UnityEngine.Object>(ResourceRequestConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token); return new UniTask<UnityEngine.Object>(ResourceRequestConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token);

View File

@ -9,25 +9,25 @@ public class ZipWrapper : MonoBehaviour
public abstract class ZipCallback public abstract class ZipCallback
{ {
/// <summary> /// <summary>
/// 压缩单个文件或文件夹前执行的回调 /// ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>ǰִ<EFBFBD>еĻص<EFBFBD>
/// </summary> /// </summary>
/// <param name="_entry"></param> /// <param name="_entry"></param>
/// <returns>如果返回true则压缩文件或文件夹反之则不压缩文件或文件夹</returns> /// <returns><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>true<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD>У<EFBFBD><EFBFBD><EFBFBD>֮<EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD></returns>
public virtual bool OnPreZip(ZipEntry _entry) public virtual bool OnPreZip(ZipEntry _entry)
{ {
return true; return true;
} }
/// <summary> /// <summary>
/// 压缩单个文件或文件夹后执行的回调 /// ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD>к<EFBFBD>ִ<EFBFBD>еĻص<EFBFBD>
/// </summary> /// </summary>
/// <param name="_entry"></param> /// <param name="_entry"></param>
public virtual void OnPostZip(ZipEntry _entry) { } public virtual void OnPostZip(ZipEntry _entry) { }
/// <summary> /// <summary>
/// 压缩执行完毕后的回调 /// ѹ<EFBFBD><EFBFBD>ִ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϻ<EFBFBD>Ļص<EFBFBD>
/// </summary> /// </summary>
/// <param name="_result">true表示压缩成功false表示压缩失败</param> /// <param name="_result">true<EFBFBD><EFBFBD>ʾѹ<EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD>false<EFBFBD><EFBFBD>ʾѹ<EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD></param>
public virtual void OnFinished(bool _result) { } public virtual void OnFinished(bool _result) { }
} }
#endregion #endregion
@ -36,36 +36,36 @@ public class ZipWrapper : MonoBehaviour
public abstract class UnzipCallback public abstract class UnzipCallback
{ {
/// <summary> /// <summary>
/// 解压单个文件或文件夹前执行的回调 /// <EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>ǰִ<EFBFBD>еĻص<EFBFBD>
/// </summary> /// </summary>
/// <param name="_entry"></param> /// <param name="_entry"></param>
/// <returns>如果返回true则压缩文件或文件夹反之则不压缩文件或文件夹</returns> /// <returns><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>true<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD>У<EFBFBD><EFBFBD><EFBFBD>֮<EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD></returns>
public virtual bool OnPreUnzip(ZipEntry _entry) public virtual bool OnPreUnzip(ZipEntry _entry)
{ {
return true; return true;
} }
/// <summary> /// <summary>
/// 解压单个文件或文件夹后执行的回调 /// <EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD>к<EFBFBD>ִ<EFBFBD>еĻص<EFBFBD>
/// </summary> /// </summary>
/// <param name="_entry"></param> /// <param name="_entry"></param>
public virtual void OnPostUnzip(ZipEntry _entry) { } public virtual void OnPostUnzip(ZipEntry _entry) { }
/// <summary> /// <summary>
/// 解压执行完毕后的回调 /// <EFBFBD><EFBFBD>ѹִ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϻ<EFBFBD>Ļص<EFBFBD>
/// </summary> /// </summary>
/// <param name="_result">true表示解压成功false表示解压失败</param> /// <param name="_result">true<EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD>ѹ<EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD>false<EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD>ѹʧ<EFBFBD><EFBFBD></param>
public virtual void OnFinished(bool _result) { } public virtual void OnFinished(bool _result) { }
} }
#endregion #endregion
/// <summary> /// <summary>
/// 压缩文件和文件夹 /// ѹ<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>
/// </summary> /// </summary>
/// <param name="_fileOrDirectoryArray">文件夹路径和文件名</param> /// <param name="_fileOrDirectoryArray"><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="_outputPathName">压缩后的输出路径文件名</param> /// <param name="_outputPathName">ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="_password">压缩密码</param> /// <param name="_password">ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="_zipCallback">ZipCallback对象,负责回调</param> /// <param name="_zipCallback">ZipCallback<EFBFBD><EFBFBD><EFBFBD>󣬸<EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD></param>
/// <returns></returns> /// <returns></returns>
public static bool Zip(List< string> _fileOrDirectoryArray, string _outputPathName, string _password = null, ZipCallback _zipCallback = null) public static bool Zip(List< string> _fileOrDirectoryArray, string _outputPathName, string _password = null, ZipCallback _zipCallback = null)
{ {
@ -78,7 +78,7 @@ public class ZipWrapper : MonoBehaviour
} }
ZipOutputStream zipOutputStream = new ZipOutputStream(File.Create(_outputPathName)); ZipOutputStream zipOutputStream = new ZipOutputStream(File.Create(_outputPathName));
zipOutputStream.SetLevel(6); // 压缩质量和压缩速度的平衡点 zipOutputStream.SetLevel(6); // ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD><EFBFBD>ٶȵ<EFBFBD>ƽ<EFBFBD><EFBFBD><EFBFBD>
if (!string.IsNullOrEmpty(_password)) if (!string.IsNullOrEmpty(_password))
zipOutputStream.Password = _password; zipOutputStream.Password = _password;
@ -110,12 +110,12 @@ public class ZipWrapper : MonoBehaviour
} }
/// <summary> /// <summary>
/// 解压Zip包 /// <EFBFBD><EFBFBD>ѹZip<EFBFBD><EFBFBD>
/// </summary> /// </summary>
/// <param name="_filePathName">Zip包的文件路径名</param> /// <param name="_filePathName">Zip<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>·<EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="_outputPath">解压输出路径</param> /// <param name="_outputPath"><EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD></param>
/// <param name="_password">解压密码</param> /// <param name="_password"><EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="_unzipCallback">UnzipCallback对象,负责回调</param> /// <param name="_unzipCallback">UnzipCallback<EFBFBD><EFBFBD><EFBFBD>󣬸<EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD></param>
/// <returns></returns> /// <returns></returns>
public static bool UnzipFile(string _filePathName, string _outputPath, string _password = null, UnzipCallback _unzipCallback = null) public static bool UnzipFile(string _filePathName, string _outputPath, string _password = null, UnzipCallback _unzipCallback = null)
{ {
@ -143,12 +143,12 @@ public class ZipWrapper : MonoBehaviour
} }
/// <summary> /// <summary>
/// 解压Zip包 /// <EFBFBD><EFBFBD>ѹZip<EFBFBD><EFBFBD>
/// </summary> /// </summary>
/// <param name="_fileBytes">Zip包字节数组</param> /// <param name="_fileBytes">Zip<EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="_outputPath">解压输出路径</param> /// <param name="_outputPath"><EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD></param>
/// <param name="_password">解压密码</param> /// <param name="_password"><EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="_unzipCallback">UnzipCallback对象,负责回调</param> /// <param name="_unzipCallback">UnzipCallback<EFBFBD><EFBFBD><EFBFBD>󣬸<EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD></param>
/// <returns></returns> /// <returns></returns>
public static bool UnzipFile(byte[] _fileBytes, string _outputPath, string _password = null, UnzipCallback _unzipCallback = null) public static bool UnzipFile(byte[] _fileBytes, string _outputPath, string _password = null, UnzipCallback _unzipCallback = null)
{ {
@ -171,12 +171,95 @@ public class ZipWrapper : MonoBehaviour
} }
/// <summary> /// <summary>
/// 解压Zip包 /// 清理和验证 ZIP 条目名称,防止路径遍历攻击
/// </summary> /// </summary>
/// <param name="_inputStream">Zip包输入流</param> /// <param name="entryName">ZIP 条目名称(可能包含路径遍历字符)</param>
/// <param name="_outputPath">解压输出路径</param> /// <param name="outputPath">输出目录路径</param>
/// <param name="_password">解压密码</param> /// <returns>清理后的安全路径,如果路径不安全则返回 null</returns>
/// <param name="_unzipCallback">UnzipCallback对象负责回调</param> private static string SanitizeZipEntryName(string entryName, string outputPath)
{
if (string.IsNullOrEmpty(entryName))
{
return null;
}
// 规范化路径分隔符(统一使用正斜杠或反斜杠)
string normalizedName = entryName.Replace('\\', '/');
// 移除路径遍历字符(.. 和 .
string[] parts = normalizedName.Split('/');
List<string> safeParts = new List<string>();
foreach (string part in parts)
{
if (string.IsNullOrEmpty(part) || part == ".")
{
// 跳过空字符串和当前目录引用
continue;
}
else if (part == "..")
{
// 如果遇到父目录引用,移除最后一个安全部分(如果存在)
if (safeParts.Count > 0)
{
safeParts.RemoveAt(safeParts.Count - 1);
}
else
{
// 如果已经在根目录,则忽略路径遍历尝试
// 这表示恶意路径遍历,返回 null 表示拒绝
return null;
}
}
else
{
// 添加到安全部分列表
safeParts.Add(part);
}
}
if (safeParts.Count == 0)
{
return null;
}
// 重新组合安全路径
string safePath = string.Join(Path.DirectorySeparatorChar.ToString(), safeParts.ToArray());
// 额外验证:确保 safePath 不包含路径遍历字符(防御性检查)
// 检查是否包含路径遍历字符或绝对路径标识符
if (safePath.Contains("..") || (safePath.Length >= 2 && safePath[1] == ':' && safePath[0] >= 'A' && safePath[0] <= 'Z'))
{
Debug.LogWarning($"[ZipWrapper.SanitizeZipEntryName] 检测到不安全的路径片段: {safePath}");
return null;
}
// 与输出路径组合(使用已清理的安全路径)
string fullPath = Path.Combine(outputPath, safePath);
// 规范化最终路径
fullPath = Path.GetFullPath(fullPath);
string normalizedOutputPath = Path.GetFullPath(outputPath);
// 验证最终路径是否在输出目录内(防止路径遍历攻击)
if (!fullPath.StartsWith(normalizedOutputPath + Path.DirectorySeparatorChar, System.StringComparison.Ordinal)
&& fullPath != normalizedOutputPath)
{
// 路径不在预期目录内,拒绝访问
Debug.LogWarning($"[ZipWrapper.SanitizeZipEntryName] 检测到路径遍历攻击尝试: {entryName} -> {fullPath}");
return null;
}
return fullPath;
}
/// <summary>
/// <20><>ѹZip<69><70>
/// </summary>
/// <param name="_inputStream">Zip<69><70><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="_outputPath"><3E><>ѹ<EFBFBD><D1B9><EFBFBD>·<EFBFBD><C2B7></param>
/// <param name="_password"><3E><>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD></param>
/// <param name="_unzipCallback">UnzipCallback<63><6B><EFBFBD>󣬸<EFBFBD><F3A3ACB8><EFBFBD>ص<EFBFBD></param>
/// <returns></returns> /// <returns></returns>
public static bool UnzipFile(Stream _inputStream, string _outputPath, string _password = null, UnzipCallback _unzipCallback = null) public static bool UnzipFile(Stream _inputStream, string _outputPath, string _password = null, UnzipCallback _unzipCallback = null)
{ {
@ -188,11 +271,11 @@ public class ZipWrapper : MonoBehaviour
return false; return false;
} }
// 创建文件目录 // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>Ŀ¼
if (!Directory.Exists(_outputPath)) if (!Directory.Exists(_outputPath))
Directory.CreateDirectory(_outputPath); Directory.CreateDirectory(_outputPath);
// 解压Zip包 // <EFBFBD><EFBFBD>ѹZip<EFBFBD><EFBFBD>
ZipEntry entry = null; ZipEntry entry = null;
using (ZipInputStream zipInputStream = new ZipInputStream(_inputStream)) using (ZipInputStream zipInputStream = new ZipInputStream(_inputStream))
{ {
@ -205,18 +288,25 @@ public class ZipWrapper : MonoBehaviour
continue; continue;
if ((null != _unzipCallback) && !_unzipCallback.OnPreUnzip(entry)) if ((null != _unzipCallback) && !_unzipCallback.OnPreUnzip(entry))
continue; // 过滤 continue; // <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
string filePathName = Path.Combine(_outputPath, entry.Name); // 使用安全验证方法清理和验证 ZIP 条目名称,防止路径遍历攻击
string filePathName = SanitizeZipEntryName(entry.Name, _outputPath);
if (filePathName == null)
{
// 路径不安全,跳过此条目
Debug.LogWarning($"[ZipWrapper.UnzipFile] 跳过不安全的 ZIP 条目: {entry.Name}");
continue;
}
// 创建文件目录 // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>Ŀ¼
if (entry.IsDirectory) if (entry.IsDirectory)
{ {
Directory.CreateDirectory(filePathName); Directory.CreateDirectory(filePathName);
continue; continue;
} }
// 写入文件 // д<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
try try
{ {
using (FileStream fileStream = File.Create(filePathName)) using (FileStream fileStream = File.Create(filePathName))
@ -256,12 +346,12 @@ public class ZipWrapper : MonoBehaviour
} }
/// <summary> /// <summary>
/// 压缩文件 /// ѹ<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
/// </summary> /// </summary>
/// <param name="_filePathName">文件路径名</param> /// <param name="_filePathName"><EFBFBD>ļ<EFBFBD>·<EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="_parentRelPath">要压缩的文件的父相对文件夹</param> /// <param name="_parentRelPath">Ҫѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD>ĸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="_zipOutputStream">压缩输出流</param> /// <param name="_zipOutputStream">ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="_zipCallback">ZipCallback对象,负责回调</param> /// <param name="_zipCallback">ZipCallback<EFBFBD><EFBFBD><EFBFBD>󣬸<EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD></param>
/// <returns></returns> /// <returns></returns>
private static bool ZipFile(string _filePathName, string _parentRelPath, ZipOutputStream _zipOutputStream, ZipCallback _zipCallback = null) private static bool ZipFile(string _filePathName, string _parentRelPath, ZipOutputStream _zipOutputStream, ZipCallback _zipCallback = null)
{ {
@ -276,7 +366,7 @@ public class ZipWrapper : MonoBehaviour
entry.DateTime = System.DateTime.Now; entry.DateTime = System.DateTime.Now;
if ((null != _zipCallback) && !_zipCallback.OnPreZip(entry)) if ((null != _zipCallback) && !_zipCallback.OnPreZip(entry))
return true; // 过滤 return true; // <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
fileStream = File.OpenRead(_filePathName); fileStream = File.OpenRead(_filePathName);
byte[] buffer = new byte[fileStream.Length]; byte[] buffer = new byte[fileStream.Length];
@ -313,12 +403,12 @@ public class ZipWrapper : MonoBehaviour
} }
/// <summary> /// <summary>
/// 压缩文件夹 /// ѹ<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>
/// </summary> /// </summary>
/// <param name="_path">要压缩的文件夹</param> /// <param name="_path">Ҫѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="_parentRelPath">要压缩的文件夹的父相对文件夹</param> /// <param name="_parentRelPath">Ҫѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD>еĸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="_zipOutputStream">压缩输出流</param> /// <param name="_zipOutputStream">ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="_zipCallback">ZipCallback对象,负责回调</param> /// <param name="_zipCallback">ZipCallback<EFBFBD><EFBFBD><EFBFBD>󣬸<EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD></param>
/// <returns></returns> /// <returns></returns>
private static bool ZipDirectory(string _path, string _parentRelPath, ZipOutputStream _zipOutputStream, ZipCallback _zipCallback = null) private static bool ZipDirectory(string _path, string _parentRelPath, ZipOutputStream _zipOutputStream, ZipCallback _zipCallback = null)
{ {
@ -331,7 +421,7 @@ public class ZipWrapper : MonoBehaviour
entry.Size = 0; entry.Size = 0;
if ((null != _zipCallback) && !_zipCallback.OnPreZip(entry)) if ((null != _zipCallback) && !_zipCallback.OnPreZip(entry))
return true; // 过滤 return true; // <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
_zipOutputStream.PutNextEntry(entry); _zipOutputStream.PutNextEntry(entry);
_zipOutputStream.Flush(); _zipOutputStream.Flush();
@ -339,7 +429,7 @@ public class ZipWrapper : MonoBehaviour
string[] files = Directory.GetFiles(_path); string[] files = Directory.GetFiles(_path);
for (int index = 0; index < files.Length; ++index) for (int index = 0; index < files.Length; ++index)
{ {
// 排除Unity中可能的 .meta 文件 // <EFBFBD>ų<EFBFBD>Unity<EFBFBD>п<EFBFBD><EFBFBD>ܵ<EFBFBD> .meta <20>ļ<EFBFBD>
if (files[index].EndsWith(".meta") == true) if (files[index].EndsWith(".meta") == true)
{ {
Debug.LogWarning(files[index] + " not to zip"); Debug.LogWarning(files[index] + " not to zip");