NLDClient-yudde/ProjectNLD/Assets/Editor/Common/BuildLauncher.cs

810 lines
30 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using AutoBuild.Helper;
using Cysharp.Threading.Tasks;
using HybridCLR.Editor;
using HybridCLR.Editor.Commands;
using HybridCLR.Editor.HotUpdate;
using PhxhSDK;
using PhxhSDK.AOT.VersionUpdate;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Obfuz.Settings;
using UnityEditor;
using UnityEngine;
using BuildTarget = UnityEditor.BuildTarget;
using Debug = UnityEngine.Debug;
using Directory = System.IO.Directory;
using YamlDotNet.Serialization;
using Obfuz4HybridCLR;
/// <summary>
/// Jenkins打包
/// </summary>
internal class BatchBuild
{
/// <summary>
/// 批处理更新设置
/// jenkins打包新包时使用该方法
/// </summary>
public static void ApplyPlayerSetting()
{
YooAssetBuildBase.Init();
}
public static string _oldDefines;
/// <summary>
/// 只在DEBUG下有
/// </summary>
private const string DEBUG = "DEBUG";
/// <summary>
/// dev上传地址
/// </summary>
private const string Dev_PostUrl = "http://dev_openapi.kedrgame.com/api/v1/";
/// <summary>
/// Pre上传地址
/// </summary>
private const string Pre_PostUrl = "http://pre_openapi.kedrgame.com/api/v1/";
/// <summary>
/// 海外Release上传地址
/// </summary>
private const string Oversea_Release_PostUrl = "http://intl_openapi.kedrgame.com/api/v1/";
/// <summary>
/// Release上传地址
/// </summary>
private const string Release_PostUrl = "http://openapi.kedrgame.com/api/v1/";
private static void WriteEncryptedJsonResource(string resourceFileNameWithoutExtension, string json)
{
var resourcesPath = "Assets/Resources";
var jsonPath = Path.Combine(resourcesPath, resourceFileNameWithoutExtension + ".json");
var bytesPath = Path.Combine(resourcesPath, resourceFileNameWithoutExtension + ".bytes");
if (!Directory.Exists(resourcesPath))
{
Directory.CreateDirectory(resourcesPath);
}
if (File.Exists(jsonPath))
{
File.Delete(jsonPath);
var metaPath = jsonPath + ".meta";
if (File.Exists(metaPath))
{
File.Delete(metaPath);
}
}
var encryptedBytes = LocalInfoEncrypt.Encrypt(Encoding.UTF8.GetBytes(json));
File.WriteAllBytes(bytesPath, encryptedBytes);
}
public static void _RevertScriptDefines()
{
var currentTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget);
PlayerSettings.SetScriptingDefineSymbolsForGroup(currentTargetGroup, _oldDefines);
}
/// <summary>
/// 批处理构建Resources和Player
/// jenkins打包新包时使用该方法
/// </summary>
public static void BuildContentAndPlayer()
{
try
{
InitChannelConfigFromYaml();
bool enableHotUpdate = YooAssetBuildBase.Init();
string bundleVersionCode = GetBundleVersionCode();
// 写入版本信息到Resources/LocalInfo.json
UpdateLocalInfo info = new()
{
workSpace = YooAssetBuildBase.workSpace,
accessKeyId = YooAssetBuildBase.appConfigAccessKeyId,
accessKeySecret = YooAssetBuildBase.appConfigAccessKeySecret,
bucketName = YooAssetBuildBase.appConfigBucketName,
configOriginalUrl = YooAssetBuildBase.appConfigURL,
//httpUrl = YooAssetBuildBase.httpURL,
httpAccessKey = YooAssetBuildBase.httpAccessKey,
httpKey = YooAssetBuildBase.httpKey,
version = YooAssetBuildBase.appVersion,
isDev = YooAssetBuildBase.isDev,
isOversea = YooAssetBuildBase.isOversea,
buildTicks = DateTime.Now.Ticks,
buildCode = bundleVersionCode,
pathRoot = "Build",
phxhBiAccessKeyId = YooAssetBuildBase.phxhBiAccessKeyId,
phxhBiScretKey = YooAssetBuildBase.phxhBiScretKey,
wxPayAppId = YooAssetBuildBase.wxPayAppId,
thinkingDataAppId = YooAssetBuildBase.thinkingDataAppId,
thinkingDataServerUrl = YooAssetBuildBase.thinkingDataServerUrl,
};
PackDataInst.CreateResourceJson(info);
BuildTargetGroup currentTargetGroup =
BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget);
string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(currentTargetGroup);
// 写入打包信息到Yoo_Build_Cache
bool isDebugBuild = false;
#if DEVELOPMENT_BUILD || DEBUG
isDebugBuild = true;
#endif
ExtBuildInfoHelper.CreateFirstExtBuildInfo(info.buildTicks, info.workSpace, info.version, info.buildCode,
isDebugBuild, defines);
BuildLauncher.SetEnableHotUpdate(enableHotUpdate);
if (enableHotUpdate)
BuildLauncher.BuildHotUpdateDlls();
YooAssetBuildBase.BuildContentAndPlayer();
// 写入打包信息到Yoo_Build_Cache
ExtBuildInfoHelper.CreateVertifyBuildInfo(info.workSpace, info.version);
// 还原宏
_RevertScriptDefines();
// 缓存打包时的文件
_CacheBuildFiles(info);
PostLoginKey(info.version); // 上传Aot loginKey
}
catch (Exception e)
{
//Build Exception用于在日志文件中定位此次打包的异常
Debug.LogError($"[Build Exception]:{e.Message} \r\n {e.StackTrace}");
throw;
}
}
private static void _CacheAotDlls(UpdateLocalInfo info)
{
string aotDllStorePath = GetAotDllStorePath(info.workSpace, info.version);
string aotDllPath = SettingsUtil.GetAssembliesPostIl2CppStripDir(EditorUserBuildSettings.activeBuildTarget);
DirectoryInfo dir = new(aotDllPath);
if (Directory.Exists(aotDllStorePath))
Directory.Delete(aotDllStorePath, true);
Directory.CreateDirectory(aotDllStorePath);
FileInfo[] files = dir.GetFiles();
foreach (FileInfo file in files)
{
file.CopyTo(Path.Combine(aotDllStorePath, file.Name), false);
}
}
private static void _CacheObfuzFiles(UpdateLocalInfo info)
{
// 备份 Assets/Obfuz/SymbolObfus 文件夹
// 备份 Library/Obfuz/{buildTarget} 文件夹
var obfuzSymbolPath = Application.dataPath + "/Obfuz/SymbolObfus";
var obfuzBuildPath = Application.dataPath + $"/../Library/Obfuz/{EditorUserBuildSettings.activeBuildTarget}";
var cacheObfuzPath = Application.dataPath + $"/../Yoo_Build_Cache/{info.workSpace}/{info.version}/CacheObfuz";
var cacheObfuzSymbolPath = cacheObfuzPath + "/SymbolObfus";;
var cacheObfuzBuildPath = cacheObfuzPath + $"/{EditorUserBuildSettings.activeBuildTarget}";
if (Directory.Exists(cacheObfuzPath))
Directory.Delete(cacheObfuzPath, true);
Directory.CreateDirectory(cacheObfuzPath);
DirectoryCopyHelper.CopyDirectory(obfuzSymbolPath, cacheObfuzSymbolPath);
DirectoryCopyHelper.CopyDirectory(obfuzBuildPath, cacheObfuzBuildPath);
}
private static void _CacheBuildFiles(UpdateLocalInfo info)
{
_CacheAotDlls(info);
if (ObfuzSettings.Instance.buildPipelineSettings.enable)
{
_CacheObfuzFiles(info);
}
}
/// <summary>
/// 批处理增量更新资源
/// jenkins打包增量更新时使用该方法
/// </summary>
public static void UpdatePreviousBuild()
{
try
{
DebugUtil.Log($"初始化渠道配置:{DateTime.Now}");
InitChannelConfigFromYaml();
DebugUtil.Log($"初始化渠道配置完成:{DateTime.Now}");
var enableHotUpdate = YooAssetBuildBase.Init();
DebugUtil.Log($"YooAssetBuildBase初始化设置完成{DateTime.Now}");
ExtBuildInfoHelper.VertifyExitBuildInfo(YooAssetBuildBase.workSpace, YooAssetBuildBase.appVersion);
DebugUtil.Log($"验证ExBuildInfo完成{DateTime.Now}");
if (enableHotUpdate)
{
Debug.Log("开始检查AOT版本");
DebugUtil.Log($"开始检查AOT Dll{DateTime.Now}");
if (CheckAotOutDate(YooAssetBuildBase.workSpace, YooAssetBuildBase.appVersion))
{
Debug.Log("AOT版本检查通过");
DebugUtil.Log($"检查AOT Dll完成{DateTime.Now}");
BuildLauncher.BuildHotUpdateDlls();
}
else
{
DebugUtil.Log($"检查AOT Dll完成{DateTime.Now}");
Debug.LogError("AOT版本不匹配请重新打AOT包");
}
}
else
{
Debug.Log("未开启热更");
}
BuildTargetGroup currentTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget);
string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(currentTargetGroup);
DebugUtil.Log($"开始打包热更资源:{DateTime.Now}");
bool result = YooAssetBuildBase.BuildOnlyResUpdate();
DebugUtil.Log($"打包热更资源完成:{DateTime.Now}");
_RevertScriptDefines();
if (result)
{
// 写入打包信息到Yoo_Build_Cache
#if DEVELOPMENT_BUILD || DEBUG
ExtBuildInfoHelper.UpdateExtBuildInfo(YooAssetBuildBase.workSpace, YooAssetBuildBase.appVersion, true,
defines);
#else
ExtBuildInfoHelper.UpdateExtBuildInfo(YooAssetBuildBase.workSpace, YooAssetBuildBase.appVersion, false, defines);
#endif
ExtBuildInfoHelper.CreateVertifyBuildInfo(YooAssetBuildBase.workSpace, YooAssetBuildBase.appVersion);
}
else
{
Debug.LogError("打包资源失败");
throw new Exception("YooAsset打包资源失败");
}
}
catch (Exception e)
{
//Build Exception用于在日志文件中定位此次打包的异常
Debug.LogError($"[Build Exception]:{e.Message} \r\n {e.StackTrace}");
throw;
}
}
/// <summary>
/// jenkins检查AOT裁剪代码
/// </summary>
/// <param name="version"></param>
/// <returns></returns>
public static bool CheckAotOutDate(string workSpace, string version)
{
Debug.Log($"开始检查aot版本:{version}");
string stripedDllPath = GetAotDllStorePath(workSpace, version);
// 先编译dll
// CompileDllCommand.CompileDllActiveBuildTarget();
PrebuildCommandExt.CompileAndObfuscateDll(); // 编译混淆dll
// 再检查编译出来的dll是否满足以前的Aotdll
MissingMetadataChecker checker = new(stripedDllPath, SettingsUtil.HotUpdateAssemblyNamesIncludePreserved);
string hotUpdateDir = SettingsUtil.GetHotUpdateDllsOutputDirByTarget(EditorUserBuildSettings.activeBuildTarget);
foreach (string dll in SettingsUtil.HotUpdateAssemblyFilesExcludePreserved)
{
string dllPath = $"{hotUpdateDir}/{dll}";
bool notAnyMissing = checker.Check(dllPath);
if (!notAnyMissing)
throw new Exception($"AOT缺失Dll({dllPath})请重新打AOT包");
}
return true;
}
/// <summary>
/// 获取缓存的AOT Dll路径
/// </summary>
/// <param name="version"></param>
public static string GetAotDllStorePath(string workSpace, string version)
{
return Application.dataPath + $"/../Yoo_Build_Cache/{workSpace}/{version}/CacheAOTDll";
}
public static string GetBundleVersionCode()
{
#if UNITY_IOS
return PlayerSettings.iOS.buildNumber;
#elif UNITY_ANDROID
return PlayerSettings.Android.bundleVersionCode.ToString();
#else
return "";
#endif
}
/// <summary>
/// 上传登录key
/// </summary>
public static void PostLoginKey(string version)
{
string loginKey = HashUtils.MD5(version);
// 服务端签名原文包含 platform="",按字母升序排列
Dictionary<string, string> headData = PostHeader.PostHeaderInfo(new Dictionary<string, string>
{
{ "plaintext", version },
{ "platform", "" },
{ "tag", loginKey },
{ "timestamp", DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString() }
});
LoginKeyData loginKeyData = new()
{
plaintext = version,
tag = loginKey,
};
try
{
if (PackDataInst.Inst.localInfo.isDev)
{
if (PackDataInst.Inst.localInfo.isOversea)
HttpHelper.PostAsync($"{Oversea_Release_PostUrl}version", loginKeyData, headData).Forget(); // 暂时海外dev也使用Release
else
HttpHelper.PostAsync($"{Dev_PostUrl}version", loginKeyData, headData).Forget();
}
else
{
if (PackDataInst.Inst.localInfo.isOversea)
HttpHelper.PostAsync($"{Oversea_Release_PostUrl}version", loginKeyData, headData).Forget();
else
{
HttpHelper.PostAsync($"{Pre_PostUrl}version", loginKeyData, headData).Forget();
HttpHelper.PostAsync($"{Release_PostUrl}version", loginKeyData, headData).Forget();
}
}
}
catch (Exception e)
{
Debug.LogError($"[PostLoginKey Exception]:{e.Message} \r\n {e.StackTrace}");
throw;
}
}
/// <summary>
/// 自动发布debug loginKey
/// </summary>
public static void PostDebugSendKey()
{
string version = PackDataInst.Inst.localInfo.version;
string tag = HashUtils.MD5(version);
// 服务端签名原文包含 platform="0",按字母升序排列
Dictionary<string, string> dicHeadData = PostHeader.PostHeaderInfo(new Dictionary<string, string>
{
{ "plaintext", version },
{ "platform", "0" },
{ "tag", tag },
{ "timestamp", DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString() }
});
SendVersionBody body = new()
{
plaintext = version,
tag = tag,
platform = "0"
};
Debug.Log($"[PostDebugSendKey] version={version}, tag={tag}");
HttpHelper.PostAsync($"{Dev_PostUrl}sendVersion", body, dicHeadData).Forget();
}
#if UNITY_EDITOR
[UnityEditor.MenuItem("Test/Build/测试 Version (version=1.0.0)")]
public static void TestPostDebugSendKey()
{
const string testVersion = "1.0.0";
string loginKey = HashUtils.MD5(testVersion);
string timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
// 服务端签名算法MD5(排序参数字符串) + httpKey 再做 SHA25664位
// 即 PostHeader.PostHeaderInfo 内部已实现的流程,参数需包含 platform=""
Dictionary<string, string> signParams = new Dictionary<string, string>
{
{ "plaintext", testVersion },
{ "platform", "" },
{ "tag", loginKey },
{ "timestamp", timestamp }
};
var sortedKeys = signParams.Keys.OrderBy(k => k).ToList();
string sortParamsStr = string.Join("&", sortedKeys.Select(k => $"{k}={signParams[k]}"));
Debug.Log($"[TestPostLoginKey] 签名原文: {sortParamsStr}");
// 使用 PostHeaderInfo 生成 64 位 signatureMD5 + httpKey + SHA256
Dictionary<string, string> headData = PostHeader.PostHeaderInfo(signParams);
Debug.Log($"[TestPostLoginKey] signature: {headData["signature"]}");
LoginKeyData loginKeyData = new()
{
plaintext = testVersion,
tag = loginKey,
};
string bodyJson = JsonUtility.ToJson(loginKeyData);
Debug.Log($"[TestPostLoginKey] 请求 Body: {bodyJson}");
string testUrl = $"{Dev_PostUrl}version";
try
{
Debug.Log($"[TestPostLoginKey] URL: {testUrl}");
HttpHelper.PostAsync(testUrl, loginKeyData, headData).Forget();
}
catch (Exception e)
{
Debug.LogError($"[TestPostLoginKey Exception]:{e.Message} \r\n {e.StackTrace}");
throw;
}
}
[UnityEditor.MenuItem("Test/Build/测试 SendVersion (version=1.0.0)")]
public static void TestPostSendVersion()
{
const string testVersion = "1.0.0";
string loginKey = HashUtils.MD5(testVersion);
string timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
// sendVersion 签名参数包含 platform="0"(服务端用 strconv.Atoi 解析)
Dictionary<string, string> signParams = new Dictionary<string, string>
{
{ "plaintext", testVersion },
{ "platform", "0" },
{ "tag", loginKey },
{ "timestamp", timestamp }
};
var sortedKeys = signParams.Keys.OrderBy(k => k).ToList();
string sortParamsStr = string.Join("&", sortedKeys.Select(k => $"{k}={signParams[k]}"));
Debug.Log($"[TestPostSendVersion] 签名原文: {sortParamsStr}");
Dictionary<string, string> headData = PostHeader.PostHeaderInfo(signParams);
Debug.Log($"[TestPostSendVersion] signature: {headData["signature"]}");
SendVersionBody body = new()
{
plaintext = testVersion,
tag = loginKey,
platform = "0"
};
string bodyJson = JsonUtility.ToJson(body);
Debug.Log($"[TestPostSendVersion] 请求 Body: {bodyJson}");
string testUrl = $"{Dev_PostUrl}sendVersion";
try
{
Debug.Log($"[TestPostSendVersion] URL: {testUrl}");
HttpHelper.PostAsync(testUrl, body, headData).Forget();
}
catch (Exception e)
{
Debug.LogError($"[TestPostSendVersion Exception]:{e.Message} \r\n {e.StackTrace}");
throw;
}
}
#endif
[System.Serializable]
private class LoginKeyData
{
public string plaintext;
public string tag;
public string platform;
}
/// <summary>
/// /sendVersion 接口 Body
/// platform 服务端内部用 strconv.Atoi 解析,必须为可转整数的字符串(空字符串会报错)
/// </summary>
[System.Serializable]
private class SendVersionBody
{
public string plaintext;
public string tag;
public string platform = "0"; // 服务端需要可转整数的字符串,"0" 表示未指定平台
}
private class LoginKeyResData
{
public int code;
public string message;
public object data;
}
private class ChannelConfig
{
public List<string> Define_list { get; set; }
public string PackageName { get; set; }
public bool IsOversea { get; set; }
public int BuildCode { get; set; }
public string ConfigAccessKeyId { get; set; }
public string ConfigAccessKeySecret { get; set; }
public string ConfigBucketName { get; set; }
public string ConfigURL { get; set; }
public string AppAccessKey { get; set; }
public string AppKey { get; set; }
public string PhxhBiAccessKeyId { get; set; }
public string PhxhBiScretKey { get; set; }
public string WxPayAppId { get; set; }
public CrashSightConfig CrashSight_Android { get; set; }
public CrashSightConfig CrashSight_iOS { get; set; }
public TalkingDataConfig TalkingData { get; set; }
public ThinkingDataConfig ThinkingData { get; set; }
}
private class CrashSightConfig
{
[YamlMember(Alias = "id")] public string Id { get; set; }
[YamlMember(Alias = "key")] public string Key { get; set; }
}
private class TalkingDataConfig
{
[YamlMember(Alias = "appid")] public string appId { get; set; }
[YamlMember(Alias = "channel")] public string channel { get; set; }
}
private class ThinkingDataConfig
{
[YamlMember(Alias = "appid")] public string appId { get; set; }
[YamlMember(Alias = "serverurl")] public string serverUrl { get; set; }
}
private const string ChannelSettingYaml = "/../ChannelSetting.yaml";
/// <summary>
/// 从YAML文件初始化渠道配置
/// </summary>
private static void InitChannelConfigFromYaml()
{
List<string> appendDefineList = new();
// 判断是否为开发模式
if (EditorUserBuildSettings.development)
{
appendDefineList.Add(DEBUG);
Debug.Log("追加宏定义:" + DEBUG);
}
string yamlPath = Application.dataPath + ChannelSettingYaml;
if (File.Exists(yamlPath))
{
try
{
// 忽略 YAML 中多余的字段
var deserializer = new DeserializerBuilder()
.IgnoreUnmatchedProperties()
.Build();
string yamlContent = File.ReadAllText(yamlPath);
var config = deserializer.Deserialize<ChannelConfig>(yamlContent);
// 处理宏定义
if (config.Define_list != null)
{
foreach (string define in config.Define_list)
{
string cleanDefine = define.Trim();
if (!string.IsNullOrEmpty(cleanDefine))
{
appendDefineList.Add(cleanDefine);
Debug.Log("追加宏定义:" + cleanDefine);
}
}
}
// 处理包名
if (!string.IsNullOrEmpty(config.PackageName))
{
Debug.Log("设置新包名:" + config.PackageName);
if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android)
{
PlayerSettings.applicationIdentifier = config.PackageName;
}
}
YooAssetBuildBase.isOversea = config.IsOversea;
// 处理BuildCode
// 若命令行已通过 -buildCode 传入(由 version_code_manager.py 自动递增),优先使用命令行值,不用 YAML 覆盖
bool hasCmdBuildCode = System.Array.Exists(
Environment.GetCommandLineArgs(), a => a == "-buildCode");
if (hasCmdBuildCode)
{
Debug.Log($"[BuildCode] 命令行已传入 -buildCode跳过 YAML 中 BuildCode={config.BuildCode} 的覆盖");
}
else if (config.BuildCode != 0)
{
Debug.Log("设置BuildCode:" + config.BuildCode);
#if UNITY_IOS
PlayerSettings.iOS.buildNumber = config.BuildCode.ToString();
#elif UNITY_ANDROID
PlayerSettings.Android.bundleVersionCode = config.BuildCode;
#endif
}
// 处理AppConfig上传id
if (config.ConfigAccessKeyId != null)
{
YooAssetBuildBase.appConfigAccessKeyId = config.ConfigAccessKeyId;
Debug.Log($"设置AppConfig上传id:{YooAssetBuildBase.appConfigAccessKeyId}");
}
// 处理AppConfig上传key
if (config.ConfigAccessKeySecret != null)
{
YooAssetBuildBase.appConfigAccessKeySecret = config.ConfigAccessKeySecret;
Debug.Log($"设置AppConfig上传key:{YooAssetBuildBase.appConfigAccessKeySecret}");
}
// 处理AppConfig上传桶名
if (config.ConfigBucketName != null)
{
YooAssetBuildBase.appConfigBucketName = config.ConfigBucketName;
Debug.Log($"设置AppConfig上传桶名:{YooAssetBuildBase.appConfigBucketName}");
}
// 处理AppConfig上传url
if (config.ConfigURL != null)
{
YooAssetBuildBase.appConfigURL = config.ConfigURL;
Debug.Log($"设置AppConfig上传url:{YooAssetBuildBase.appConfigURL}");
}
// 处理http请求AccessKey
if (config.AppAccessKey != null)
{
YooAssetBuildBase.httpAccessKey = config.AppAccessKey;
Debug.Log($"设置http请求id:{YooAssetBuildBase.httpAccessKey}");
}
// 处理http请求AppKey
if (config.AppKey != null)
{
YooAssetBuildBase.httpKey = config.AppKey;
Debug.Log($"设置http请求id:{YooAssetBuildBase.httpKey}");
}
// 处理BI AccessKeyId
if (config.PhxhBiAccessKeyId != null)
{
YooAssetBuildBase.phxhBiAccessKeyId = config.PhxhBiAccessKeyId;
Debug.Log($"设置BI AccessKeyId:{YooAssetBuildBase.phxhBiAccessKeyId}");
}
// 处理BI SecretKey
if (config.PhxhBiScretKey != null)
{
YooAssetBuildBase.phxhBiScretKey = config.PhxhBiScretKey;
Debug.Log($"设置BI SecretKey:{YooAssetBuildBase.phxhBiScretKey}");
}
// 处理微信支付 AppID
if (config.WxPayAppId != null)
{
YooAssetBuildBase.wxPayAppId = config.WxPayAppId;
Debug.Log($"设置微信支付 AppID:{YooAssetBuildBase.wxPayAppId}");
}
// 处理CrashSight_Android配置
if (config.CrashSight_Android != null &&
EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android)
{
var crashSightData = new PhxhSDK.Data.CrashSightData
{
id = config.CrashSight_Android.Id,
key = config.CrashSight_Android.Key
};
var json = JsonUtility.ToJson(crashSightData);
WriteEncryptedJsonResource("CrashSightData", json);
Debug.Log("CrashSight配置已保存:" + crashSightData.id + "|" + crashSightData.key);
}
// 处理CrashSight_iOS配置
if (config.CrashSight_iOS != null &&
EditorUserBuildSettings.activeBuildTarget == BuildTarget.iOS)
{
var crashSightData = new PhxhSDK.Data.CrashSightData
{
id = config.CrashSight_iOS.Id,
key = config.CrashSight_iOS.Key
};
var json = JsonUtility.ToJson(crashSightData);
WriteEncryptedJsonResource("CrashSightData", json);
Debug.Log("CrashSight配置已保存:" + crashSightData.id + "|" + crashSightData.key);
}
if (config.TalkingData != null)
{
var talkingDataInitTool = new TalkingDataInitTool
{
appID = config.TalkingData.appId,
channel = config.TalkingData.channel
};
var json = JsonUtility.ToJson(talkingDataInitTool);
WriteEncryptedJsonResource("TalkingDataInitConfig", json);
Debug.Log("TalkingData配置已保存:" + talkingDataInitTool.appID + "|" + talkingDataInitTool.channel);
}
// 处理数数科技(ThinkingData)配置
if (config.ThinkingData != null)
{
YooAssetBuildBase.thinkingDataAppId = config.ThinkingData.appId;
YooAssetBuildBase.thinkingDataServerUrl = config.ThinkingData.serverUrl;
Debug.Log($"设置数数科技 AppID:{YooAssetBuildBase.thinkingDataAppId}");
Debug.Log($"设置数数科技 ServerUrl:{YooAssetBuildBase.thinkingDataServerUrl}");
}
// 更新宏定义
var currentTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget);
var oldDefines = PlayerSettings.GetScriptingDefineSymbolsForGroup(currentTargetGroup);
_oldDefines = oldDefines;
if (appendDefineList.Count > 0)
{
var newDefineList = new List<string>();
newDefineList.AddRange(oldDefines.Split(';'));
for (var i = 0; i < newDefineList.Count; i++)
{
var define = newDefineList[i];
if (string.IsNullOrEmpty(define))
continue;
if (appendDefineList.Contains(define))
appendDefineList.Remove(define);
}
newDefineList.AddRange(appendDefineList);
PlayerSettings.SetScriptingDefineSymbolsForGroup(currentTargetGroup,
string.Join(";", newDefineList));
}
// 关闭Unity闪屏
PlayerSettings.SplashScreen.showUnityLogo = false;
}
catch (Exception e)
{
Debug.LogError($"解析YAML配置文件失败: {e.Message}\n{e.StackTrace}");
throw;
}
}
else
{
Debug.LogError($"找不到渠道配置文件: {yamlPath}");
}
}
}