TuyooSDKPackage/Packages/com.bywaystudios.tuyoosdk/Editor/Android/TySdkProjectGenerator.cs
2025-12-06 10:50:57 +08:00

257 lines
11 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 System.IO;
using System.Xml;
using System.Collections.Generic;
using UnityEditor;
using System.Text.RegularExpressions;
using System;
#if UNITY_EDITOR && UNITY_ANDROID
using UnityEngine;
using UnityEditor.Android;
class TySdkProjectGenerator : IPostGenerateGradleAndroidProject
{
public int callbackOrder { get { return 0; } }
public static string sdkInUnityRootPath;
public static string rootProjectPath;
public static string assetsRootPath;
/**
* 要做的事情:
* 1. AndroidManifest修改
1. activity \ applciatoin 修改
2. 添加插件
仓库、声明、脚本
3. 拷贝json配置文件
*
**/
public void OnPostGenerateGradleAndroidProject(string path)
{
Debug.Log("TySdkProjectGenerator.OnPostGenerateGradleAndroidProject at path " + path);
rootProjectPath = Directory.GetParent(path).FullName;
//获取Assets根目录
assetsRootPath = Application.dataPath;
//获取sdk在unity中的路径
//var stackTrace = new System.Diagnostics.StackTrace(true);
//var frame = stackTrace.GetFrame(0);
//string filePath = frame.GetFileName();
//sdkInUnityRootPath = Path.GetDirectoryName(filePath);
sdkInUnityRootPath = FileUtil.GetPhysicalPath("Packages/com.bywaystudios.tuyoosdk/Editor/Android");
Debug.Log("TySdkProjectGenerator.OnPostGenerateGradleAndroidProject sdkInUnityRootPath " + sdkInUnityRootPath);
//处理androidMnifest
ManifestProcessor manifestProcessor = new ManifestProcessor(Path.Combine(path, "src/main/AndroidManifest.xml"));
manifestProcessor.process();
//处理build.gradle
BuildGradleProcessor buildGradleProcessor = new BuildGradleProcessor(rootProjectPath);
buildGradleProcessor.process();
//拷贝json文件
copyJsonFile();
}
private void copyJsonFile()
{
Debug.Log("TySdkProjectGenerator.copyJsonFile start");
//package gameConfig -> root/config/..
CopyFile(Path.Combine(FileUtil.GetPhysicalPath("ProjectSettings/Packages/com.bywaystudios.tuyoosdk"), "gameconfig.json"), Path.Combine(rootProjectPath, "config", "gameconfig.json"));
CopyFile(Path.Combine(FileUtil.GetPhysicalPath("ProjectSettings/Packages/com.bywaystudios.tuyoosdk"), "gameconfig.json"), Path.Combine(rootProjectPath, "launcher", "gameconfig.json"));
//gameConfigs/.. -> root/config/..
CopyFiles(Path.Combine(sdkInUnityRootPath, "gameConfigs"), Path.Combine(rootProjectPath, "config"));
CopyFiles(Path.Combine(sdkInUnityRootPath, "gameConfigs"), Path.Combine(rootProjectPath, "launcher"));
//兼容firebase crashlytics
CopyFile(Path.Combine(FileUtil.GetPhysicalPath("ProjectSettings/Packages/com.bywaystudios.firebase"), "google-services.json"), Path.Combine(rootProjectPath, "launcher","google-services.json"));
Debug.Log("TySdkProjectGenerator.copyJsonFile end");
}
public static void CopyFile(string sourceFile, string destinationFile)
{
// 检查源文件是否存在
if (!File.Exists(sourceFile))
{
Console.WriteLine("源文件不存在: " + sourceFile);
return;
}
// 创建目标文件夹(如果不存在)
string destinationFolder = Path.GetDirectoryName(destinationFile);
if (!Directory.Exists(destinationFolder))
{
Directory.CreateDirectory(destinationFolder);
Console.WriteLine("目标文件夹已创建: " + destinationFolder);
}
// 复制文件到目标路径
File.Copy(sourceFile, destinationFile, true); // 允许覆盖
Console.WriteLine("已复制文件: " + sourceFile + " 到 " + destinationFile);
}
public static void CopyFiles(string sourceFolder, string destinationFolder)
{
// 检查源文件夹是否存在
if (!Directory.Exists(sourceFolder))
{
Console.WriteLine("源文件夹不存在: " + sourceFolder);
return;
}
// 创建目标文件夹(如果不存在)
if (!Directory.Exists(destinationFolder))
{
Directory.CreateDirectory(destinationFolder);
Console.WriteLine("目标文件夹已创建: " + destinationFolder);
}
// 获取源文件夹中的所有文件
string[] files = Directory.GetFiles(sourceFolder);
// 复制每个文件到目标文件夹
foreach (string file in files)
{
if (!file.EndsWith("json"))
{
continue;
}
string fileName = Path.GetFileName(file); // 获取文件名
string destFile = Path.Combine(destinationFolder, fileName); // 组合目标文件路径
File.Copy(file, destFile, true); // 复制文件,允许覆盖
Console.WriteLine("已复制文件: " + file + " 到 " + destFile);
}
}
internal class ManifestProcessor
{
private string manifestPath;
public ManifestProcessor(string manifestPath)
{
Debug.Log("ManifestProcessor, manifestPath:" + manifestPath);
this.manifestPath = manifestPath;
}
// 1. 处理Applicatioin
// 2. 处理Activity
public void process()
{
Debug.Log("ManifestProcessor, process start.");
if (!File.Exists(manifestPath))
{
Debug.LogError("manifestPath not exit!! manifestPath:" + manifestPath);
return;
}
// 加载AndroidManifest.xml文件
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(manifestPath);
// 定义 Android 命名空间
string androidNamespaceURI = "http://schemas.android.com/apk/res/android";
// 获取<manifest>节点
XmlNode manifestNode = xmlDoc.SelectSingleNode("/manifest");
if (manifestNode == null)
{
Debug.LogError("manifestNode is NULL!!");
return;
}
// 获取<application>节点
XmlNode applicationNode = manifestNode.SelectSingleNode("application");
if (applicationNode == null)
{
Debug.LogError("applicationNode is NULL!!");
return;
}
// 设置name属性
XmlAttribute nameAttribute = applicationNode.Attributes["android:name"];
var applicationName = "android.app.Application";
if (nameAttribute == null || nameAttribute.Value.Equals(applicationName))
{
//默认application修改成sdk的application
Debug.Log("修改成SDK的application");
// 修改已有的name属性
if(nameAttribute == null){
nameAttribute = xmlDoc.CreateAttribute("android:name", androidNamespaceURI);
nameAttribute.Value = "com.tuyoo.sdk.Application";
applicationNode.Attributes.Append(nameAttribute);
}else{
nameAttribute.Value = "com.tuyoo.sdk.Application";
}
}
else
{
//游戏自定义了application,不做处理了
Debug.Log("游戏自定义了application,不做处理了,需要游戏自行处理sdk接口调用");
}
// 复制sdk的application到游戏中。
var tuyooJavaDir = Path.Combine(rootProjectPath, "unityLibrary/src/main/java/com/tuyoo/sdk");
if (!Directory.Exists(tuyooJavaDir))
{
Directory.CreateDirectory(tuyooJavaDir);
Console.WriteLine("文件夹创建成功: " + tuyooJavaDir);
}
//设置sdk的application继承游戏的applicaiton
var sdkApplicationContent = File.ReadAllText(Path.Combine(sdkInUnityRootPath, "sdkConfigs", "Application.txt"));
sdkApplicationContent = sdkApplicationContent.Replace(@"${0}", applicationName);
File.WriteAllText(Path.Combine(tuyooJavaDir, "Application.java"), sdkApplicationContent);
// 创建命名空间管理器,并添加命名空间
XmlNamespaceManager nsManager = new XmlNamespaceManager(xmlDoc.NameTable);
nsManager.AddNamespace("android", androidNamespaceURI);
// 查找主Activity包含<meta-data android:name="unityplayer.UnityActivity" android:value="true" /> 的<activity>节点
XmlNode mainActivity = xmlDoc.SelectSingleNode("/manifest/application/activity[meta-data[@android:name='unityplayer.UnityActivity' and @android:value='true']]", nsManager);
Debug.Log("mainActivity :" + mainActivity.Attributes["android:name"]);
// 找到主Activity修改android:name属性
XmlAttribute nameAttribute1 = mainActivity.Attributes["android:name"];
var activityName = "com.unity3d.player.UnityPlayerActivity";
if (nameAttribute1 == null || nameAttribute1.Value.Equals(activityName))
{
Debug.Log("游戏使用的默认Activity插件替换成SDK的Activity");
if(nameAttribute1 == null){
nameAttribute1 = xmlDoc.CreateAttribute("android", "name", androidNamespaceURI);
nameAttribute1.Value = "com.tuyoo.sdk.Activity";
mainActivity.Attributes.Append(nameAttribute1);
}else{
nameAttribute1.Value = "com.tuyoo.sdk.Activity";
}
}
else
{
Debug.Log("游戏自定义了MainActivity因此插件不做处理,由游戏自行调用SDK声明周期接口");
}
//将SDK的activity引入的游戏
if (!Directory.Exists(tuyooJavaDir))
{
Directory.CreateDirectory(tuyooJavaDir);
Console.WriteLine("文件夹创建成功: " + tuyooJavaDir);
}
//设置sdk的application继承游戏的applicaiton
var sdkActivityContent = File.ReadAllText(Path.Combine(sdkInUnityRootPath, "sdkConfigs", "Activity.txt"));
sdkActivityContent = sdkActivityContent.Replace(@"${0}", activityName);
File.WriteAllText(Path.Combine(tuyooJavaDir, "Activity.java"), sdkActivityContent);
// 保存修改后的AndroidManifest.xml文件
xmlDoc.Save(manifestPath);
UnityEngine.Debug.Log("AndroidManifest.xml 已修改,设置 application name 为 com.tuyoo.sdk.Application.");
UnityEngine.Debug.Log("AndroidManifest.xml 已修改设置主Activity为 com.tuyoo.sdk.Activity.");
}
}
}
#endif