257 lines
11 KiB
C#
257 lines
11 KiB
C#
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 |