using System;
using System.Reflection;
using HarmonyLib;
using Minio.DataModel;
using Minio.Exceptions;
namespace Hopetry.Provider
{
public class PartSizeOverride
{
private static Harmony _harmony;
///
/// 使用Harmony动态替换MinIO的分片计算逻辑
///
public static void OverrideMinioCalculator()
{
try
{
// 初始化Harmony实例
_harmony = new Harmony("com.hopetry.minio.patch");
// 获取原始方法和自定义方法
var originalMethod = typeof(Minio.Helper.Utils).GetMethod(
"CalculateMultiPartSize",
BindingFlags.Static | BindingFlags.Public,
null,
new[] { typeof(long), typeof(bool) },
null);
var customMethod = typeof(PartSizeOverride).GetMethod(
"CustomCalculateMultiPartSize",
BindingFlags.Static | BindingFlags.NonPublic);
if (originalMethod == null || customMethod == null)
throw new InvalidOperationException("Method not found");
// 应用Harmony补丁(替换原始方法)
_harmony.Patch(originalMethod,
new HarmonyMethod(customMethod));
Console.WriteLine("Method override successful");
}
catch (Exception ex)
{
Console.WriteLine($"Override failed: {ex.Message}");
throw;
}
}
///
/// 自定义分片计算逻辑(需严格匹配原始方法签名)
///
private static bool CustomCalculateMultiPartSize(ref MultiPartInfo __result, long size, bool copy)
{
// 原计算逻辑保持不变
long MaxParts = 10000;
long MinimumPartSize = 5 * 1024L * 1024L;
long MinimumPUTPartSize = 16 * 1024L * 1024L;
long MaximumStreamObjectSize = MaxParts * MinimumPartSize;
long MaxMultipartPutObjectSize = 1024L * 1024L * 1024L * 1024L * 5;
if (size == -1) size = MaximumStreamObjectSize;
long MinimumCOPYPartSize = 512 * 1024L * 1024L;
if (size > MaxMultipartPutObjectSize)
throw new EntityTooLargeException(
$"Your proposed upload size {size} exceeds the maximum allowed object size {MaxMultipartPutObjectSize}");
var partSize = (double)Math.Ceiling((decimal)size / MaxParts);
var minPartSize = copy ? MinimumCOPYPartSize : MinimumPartSize;
partSize = (double)Math.Ceiling((decimal)partSize / minPartSize) * minPartSize;
var partCount = Math.Ceiling(size / partSize);
var lastPartSize = size - ((partCount - 1) * partSize);
__result = new MultiPartInfo
{
PartSize = partSize,
PartCount = partCount,
LastPartSize = lastPartSize
};
// 跳过原始方法执行
return false;
}
}
}