miduo_client/Assets/Editor/AutoPack.cs

602 lines
22 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 UnityEngine;
using UnityEditor;
using System.IO;
using System;
using GameEditor.FrameTool;
using GameEditor.Util;
using System.Collections;
using System.Collections.Generic;
public class PackConfig
{
public string name;
public string scene;
public string project;
public string version;
public string bench;
public PackConfig(string _name, string _scene, string _project, string _version, string _bench)
{
name = _name;
scene = _scene;
project = _project;
version= _version;
bench = _bench;
}
}
public class AutoPack : EditorWindow
{
static List<PackConfig> PackConfig = new List<PackConfig>();
#if UNITY_ANDROID
static string Platform = "Android";
static string ConfigFileName = "config.txt";
static string VersionFileName = "version.txt";
#elif UNITY_IOS
static string Platform = "IOS";
static string ConfigFileName = "config.txt";
static string VersionFileName = "version.txt";
#else
static string Platform = "Android";
static string ConfigFileName = "config.txt";
static string VersionFileName = "version.txt";
#endif
static string MomPackPath;
static string ExportPackPath;
static string ScenePath;
static string ABPath;
static string APKPath;
static string PackTime;
static bool CommitToGit;
// 判断是否要重新导出工程
static string[] ExportTypeList =
{
"导出工程,替换出包",
"只替换AB出包",
"只出包"
};
static int ExportType;
static bool[] Chooser;
static bool isObb = false;
static string benchName; // 当前所在分支
private void OnEnable()
{
MomPackPath = EditorPrefs.GetString("MomPackPath", "");
ExportPackPath = Application.dataPath.Replace("Assets", "ExportProject");
ScenePath = Application.dataPath + "/LuaFramework/Scenes/";
ABPath = Application.dataPath + "/../BuildABs/" + Platform + "/";
ExportType = 2;
// 加载配置
LoadConfig();
}
static void LoadConfig()
{
PackConfig.Clear();
Hashtable config = ClientConfigManager.Instance.GetAutoPackConfig();
foreach (string k in config.Keys)
{
Hashtable ht = config[k] as Hashtable;
string name = k;
string scene = ht["scene"] as string;
string project = ht["project"] as string;
string version = ht["version"] as string;
string bench = ht["bench"] as string;
PackConfig.Add(new PackConfig(name, scene, project, version, bench));
}
Chooser = new bool[PackConfig.Count];
}
/// <summary>
/// 版本文件路径
/// </summary>
static string _MomPackPath
{
get
{
return MomPackPath + "/" + Platform + "/";
}
}
//bool isBuild = false;
//static bool isZs = false;
//static string[] versionArr = new string[15];
//static int verIndex = 0;
//static string curProjectDir;
//static string m_ExcelPath;
//static string[] excelArr;
//static int excelIndex=0;
//打包数据
[MenuItem("自动化打包/一键导出")]
private static void EzBuildPack()
{
benchName = GitUtil.GetCurBenchName();
UnityEngine.Debug.Log("当前分支:" + benchName);
//创建窗口
Rect wr = new Rect(0, 0, 500, 1000);
var buildWin = GetWindowWithRect<AutoPack>(wr, true);
buildWin.titleContent = new GUIContent("打包工具");
buildWin.Show();
}
//[MenuItem("自动化打包/一键导出2")]
//private static void EzBuildPack2()
//{
// //创建窗口
// string[] ss = ProcessUtil.OpenFileWin();
// foreach(string s in ss)
// {
// Debug.Log(s);
// }
//}
private void OnGUI()
{
EditorGUILayout.BeginVertical();
EditorGUILayout.Space();
EditorGUILayout.Space();
//EditorGUILayout.LabelField("");
MomPackPath = EditorGUILayout.TextField("母包工程地址:", MomPackPath);
if (GUILayout.Button("Browse", GUILayout.ExpandWidth(false)))
{
MomPackPath = EditorUtility.OpenFolderPanel("Resource path", MomPackPath, MomPackPath);
EditorPrefs.SetString("MomPackPath", MomPackPath);
}
EditorGUILayout.Space();
EditorGUILayout.Space();
EditorGUILayout.LabelField("请选择要打的包:");
for(int i = 0; i < PackConfig.Count; i++)
{
if (PackConfig[i].bench.Equals(benchName))
{
EditorGUILayout.BeginVertical();
Chooser[i] = EditorGUILayout.ToggleLeft(PackConfig[i].name, Chooser[i]);
if (Chooser[i])
{
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("编辑Config", GUILayout.Height(20f)))
{
string tpath = ClientConfigManager.Instance.GetClientConfigPath() + "/Version/" + PackConfig[i].version + "/" + ConfigFileName;
GameEditor.Util.ProcessUtil.OpenText(tpath);
}
if (GUILayout.Button("编辑Version", GUILayout.Height(20f)))
{
string tpath = ClientConfigManager.Instance.GetClientConfigPath() + "/Version/" + PackConfig[i].version + "/" + VersionFileName;
GameEditor.Util.ProcessUtil.OpenText(tpath);
}
if (GameLogic.AppConst.PlatformPath.Equals("Android"))
{
if (GUILayout.Button("编辑Gradle", GUILayout.Height(20f)))
{
string tpath = _MomPackPath + PackConfig[i].project + "/build.gradle";
GameEditor.Util.ProcessUtil.OpenText(tpath);
}
if (GUILayout.Button("更新蓝鲸SDK", GUILayout.Height(20f)))
{
File.Copy(_MomPackPath + "BlueWhaleJar/app/build/outputs/aar/app-release.aar", _MomPackPath + PackConfig[i].project + "/libs/BlueWhale.aar", true);
Debug.Log("更新完成");
}
}
else
{
if (GUILayout.Button("同步配置文件", GUILayout.Height(20f)))
{
ReplaceConfigAndVersion(i);
}
if (GUILayout.Button("开始混淆", GUILayout.Height(20f)))
{
EncryptAB(i);
}
}
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.EndVertical();
EditorGUILayout.Space();
EditorGUILayout.Space();
}
}
ExportType = EditorGUILayout.Popup("请选择出包方式", ExportType, ExportTypeList);
EditorGUILayout.Space();
CommitToGit = EditorGUILayout.ToggleLeft("是否要提交到Git", CommitToGit);
EditorGUILayout.Space();
if (GUILayout.Button("开始", GUILayout.Height(40f)))
{
StartExport();
}
}
public static void StartExport()
{
if (MomPackPath.Equals(""))
{
EditorUtility.DisplayDialog("提示", "母包工程地址错误", "确定");
return;
}
bool check_result = false;
for (int i = 0; i < Chooser.Length; i++)
{
if (!Chooser[i]) continue;
string sceneFilePath = ScenePath + PackConfig[i].scene;
if (!File.Exists(sceneFilePath + ".unity"))
{
Debug.LogError(PackConfig[i].name + " 未找到场景:" + sceneFilePath);
check_result = true;
}
string momPath = _MomPackPath + PackConfig[i].project;
if (!Directory.Exists(momPath))
{
Debug.LogError(PackConfig[i].name + " 未找到母包:" + momPath);
check_result = true;
}
}
if (check_result)
{
EditorUtility.DisplayDialog("提示", "包路径错误", "确定");
return;
}
// 开始导出
for (int i = 0; i < Chooser.Length; i++)
{
if (!Chooser[i]) continue;
switch (ExportType) {
case 0: // 导出工程
ExportAS(i);
ReplaceFromProject(i);
ReplaceConfigAndVersion(i);
//EncryptAB(i);
GitUpdate(i);
CreateLogFile(i);
StartGradleBuild(i);
GitCommit(i);
break;
case 1: // 只替换AB
ReplaceFromAB(i);
ReplaceConfigAndVersion(i);
//EncryptAB(i);
GitUpdate(i);
CreateLogFile(i);
StartGradleBuild(i);
GitCommit(i);
break;
case 2: // 只重新打包
ReplaceConfigAndVersion(i);
GitUpdate(i);
CreateLogFile(i);
StartGradleBuild(i);
GitCommit(i);
break;
}
}
}
public static void CreateLogFile(int index)
{
APKPath = _MomPackPath + PackConfig[index].project + "/APK/";
if (!Directory.Exists(APKPath))
{
Directory.CreateDirectory(APKPath);
}
PackTime = DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss");
APKPath += PackTime;
if (!Directory.Exists(APKPath))
{
Directory.CreateDirectory(APKPath);
}
}
// 导出android 工程
public static void ExportAS(int index)
{
string pName = PackConfig[index].scene + "__" + PackConfig[index].project;
PlayerSettings.productName = pName;
PlayerSettings.Android.useAPKExpansionFiles = isObb;
if (isObb)
{
pName += "__obb";
}
if (!Directory.Exists(ExportPackPath))
{
Directory.CreateDirectory(ExportPackPath);
}
if (Directory.Exists(ExportPackPath + "/" + pName))
{
Directory.Delete(ExportPackPath + "/" + pName, true);
}
EditorUserBuildSettings.exportAsGoogleAndroidProject = true;
EditorUserBuildSettings.androidBuildSystem = AndroidBuildSystem.Gradle;
// 设置需要打包的场景
string launchScene = "Assets/LuaFramework/Scenes/" + PackConfig[index].scene + ".unity";
Debug.Log(PackConfig[index].name + ":打包场景:" + launchScene);
BuildPlayerOptions bpo = new BuildPlayerOptions();
bpo.locationPathName = ExportPackPath;
bpo.options = BuildOptions.None;
//bpo.options |= BuildOptions.AcceptExternalModificationsToPlayer;
bpo.scenes = new[] { launchScene };
bpo.target = BuildTarget.Android;
// 调用开始打包
BuildPipeline.BuildPlayer(bpo);
Debug.Log(PackConfig[index].name + "android工程导出路径" + ExportPackPath + "/" + pName);
Debug.Log(PackConfig[index].name + "android工程导出完成");
}
static string[] ReplaceDir = new string[]
{
"/src/main/assets/Android",
"/src/main/assets/bin"
};
static string[] CopyDir = new string[]
{
"/src/main/jniLibs"
};
// 从工程中替换
private static void ReplaceFromProject(int index)
{
string fromPath = ExportPackPath + "/" + PackConfig[index].scene + "__" + PackConfig[index].project;
string toPath = _MomPackPath + PackConfig[index].project;
for (int i = 0; i < ReplaceDir.Length; i++)
{
string dir = ReplaceDir[i];
string to = toPath + dir;
GameCore.FileUtils.ReplaceDir(fromPath + dir, to, (string dirName, string fileName, float progress)=>
{
EditorUtility.DisplayProgressBar("正在复制:"+ dirName, fileName, progress);
});
EditorUtility.ClearProgressBar();
}
for (int i = 0; i < CopyDir.Length; i++)
{
string dir = CopyDir[i];
string to = toPath + dir;
GameCore.FileUtils.CopyDir(fromPath + dir, to, (string dirName, string fileName, float progress) =>
{
EditorUtility.DisplayProgressBar("正在复制:" + dirName, fileName, progress);
});
EditorUtility.ClearProgressBar();
}
Debug.Log(PackConfig[index].name + ":母包工程资源替换完成");
// 替换build-id
EditorUtility.DisplayProgressBar("重写AndroidManifest", "", 0.5f);
RewriteManifest(fromPath + "/src/main/AndroidManifest.xml", toPath + "/src/main/AndroidManifest.xml");
Debug.Log(PackConfig[index].name + "母包Manifest修改完成");
EditorUtility.ClearProgressBar();
}
private static void RewriteManifest(string f, string t)
{
// 找到要替换的内容
string[] flines = File.ReadAllLines(f, System.Text.Encoding.UTF8);
string rpl = "";
for (int fi = 0; fi < flines.Length; fi++)
{
if (flines[fi].Contains("unity.build-id"))
{
rpl = flines[fi];
break;
}
}
// 判断是否正确
if (rpl.Equals(""))
{
return;
}
// 替换到母包中
string[] tlines = File.ReadAllLines(t, System.Text.Encoding.UTF8);
string[] wlines = new string[tlines.Length - 1];
string lastLine = "";
for (int ti = 0; ti < tlines.Length; ti++)
{
if (tlines[ti].Contains("unity.build-id"))
{
tlines[ti] = rpl;
}
if (ti == tlines.Length - 1)
{
lastLine = tlines[ti];
}
else
{
wlines[ti] = tlines[ti];
}
}
File.WriteAllLines(t, wlines, System.Text.Encoding.UTF8);
File.AppendAllText(t, lastLine, System.Text.Encoding.UTF8);
}
// 从AB包替换
private static void ReplaceFromAB(int index)
{
string toPath = _MomPackPath + PackConfig[index].project + "/src/main/assets/Android";
if (Directory.Exists(toPath)) Directory.Delete(toPath, true);
Directory.CreateDirectory(toPath);
GameCore.FileUtils.ReplaceDir(ABPath, toPath, (string dirName, string fileName, float progress) =>
{
EditorUtility.DisplayProgressBar("正在复制:" + dirName, fileName, progress);
});
EditorUtility.ClearProgressBar();
Debug.Log(PackConfig[index].name + "替换AB包完成");
}
// 加密AB包
private static void EncryptAB(int index)
{
string toPath = _MomPackPath + PackConfig[index].project + "/src/main/assets/Android";
if (GameLogic.AppConst.PlatformPath.Equals("IOS"))
{
toPath = _MomPackPath + PackConfig[index].project + "/Data/Raw/IOS";
}
string json = File.ReadAllText(toPath + "/"+ VersionFileName);
VersionTxt version = JsonUtility.FromJson<VersionTxt>(json);
if (version.EncyptKey != null && version.EncyptKey != "")
{
string[] pathList = Directory.GetFiles(toPath, "*.unity3d", SearchOption.AllDirectories);
float i = 0f;
Debug.Log("文件数量;" + pathList.Length);
foreach (string path in pathList)
{
GameLogic.MEncyptUtil.EncyptAB(path, version.EncyptKey);
EditorUtility.DisplayProgressBar("正在加密:", path, i++ / pathList.Length);
}
EditorUtility.ClearProgressBar();
Debug.Log(PackConfig[index].name + "加密AB包完成");
}
else {
Debug.Log(PackConfig[index].name + ":无需加密");
}
}
// 替换配置文件
private static void ReplaceConfigAndVersion(int index)
{
if (GameLogic.AppConst.PlatformPath.Equals("Android")) {
//EditorUtility.DisplayProgressBar("替换配置文件1", "", 0.5f);
string fromPath = ClientConfigManager.Instance.GetClientConfigPath() + "/Version/" + PackConfig[index].version + "/";
string toPath = _MomPackPath + PackConfig[index].project + "/Config/";
File.Copy(fromPath + ConfigFileName, toPath + ConfigFileName, true);
File.Copy(fromPath + VersionFileName, toPath + VersionFileName, true);
//EditorUtility.DisplayProgressBar("替换配置文件2", "", 0.5f);
fromPath = toPath;
toPath = _MomPackPath + PackConfig[index].project + "/src/main/assets/Android/";
File.Copy(fromPath + ConfigFileName, toPath + ConfigFileName, true);
File.Copy(fromPath + VersionFileName, toPath + VersionFileName, true);
}
else
{
//EditorUtility.DisplayProgressBar("替换配置文件", "", 0.5f);
string fromPath = ClientConfigManager.Instance.GetClientConfigPath() + "/Version/" + PackConfig[index].version + "/";
string toPath = _MomPackPath + PackConfig[index].project + "/Data/Raw/IOS/";
File.Copy(fromPath + ConfigFileName, toPath + ConfigFileName, true);
File.Copy(fromPath + VersionFileName, toPath + VersionFileName, true);
}
Debug.Log(PackConfig[index].name+":配置文件替换完成");
EditorUtility.ClearProgressBar();
}
// 开始生成apk
private static void StartGradleBuild(int index)
{
EditorUtility.DisplayProgressBar("正在生成APK", "", 0f);
GameEditor.Util.ProcessUtil.ProcessCommand(_MomPackPath + PackConfig[index].project, "gradlew assembleRelease>>" + APKPath + "/_log.txt");
EditorUtility.DisplayProgressBar("正在导出APK", "", 1f);
string versionStr = GetAPKVersionStr(PackConfig[index].project);
string apkFilePath = _MomPackPath + PackConfig[index].project + "/build/outputs/apk/release/" + PackConfig[index].project + "-release.apk";
if (File.Exists(apkFilePath))
{
File.Copy(apkFilePath, APKPath + "/" + PackConfig[index].name +"_" + versionStr + "_" + PackTime + ".apk");
}
Debug.Log(PackConfig[index].name + ":打包完成");
EditorUtility.ClearProgressBar();
}
private static string GetAPKVersionStr(string folder)
{
string tpath = _MomPackPath + folder + "/build.gradle";
string[] lines = File.ReadAllLines(tpath);
string versionCode = "";
string versionName = "";
string applicationId = "";
foreach (string l in lines)
{
string lt = l.Trim();
if (lt.StartsWith("versionCode"))
{
versionCode = lt.Split(' ')[1];
}else if (lt.StartsWith("versionName"))
{
versionName = lt.Split('\'')[1];
}
else if (lt.StartsWith("applicationId"))
{
applicationId = lt.Split('\'')[1];
}
}
return string.Format("{0}_{1}({2})", applicationId, versionName, versionCode);
}
private static void GitUpdate(int index)
{
EditorUtility.DisplayProgressBar("正在更新母包", "", 0f);
ProcessUtil.ProcessCommand(_MomPackPath, "git pull>>" + APKPath + "/_log.txt");
EditorUtility.ClearProgressBar();
}
private static void GitCommit(int index)
{
if (CommitToGit)
{
string versionStr = GetAPKVersionStr(PackConfig[index].project);
EditorUtility.DisplayProgressBar("正在提交修改", "", 0f);
string printlog = ">>" + APKPath + "/_log.txt";
string[] commands = new string[]{
"echo git add ." + printlog,
"git add ." + printlog,
"echo git commit -m 'AutoPack" + PackConfig[index].name +"_" + versionStr + "_" + PackTime + ".apk'" + printlog,
"git commit -m 'AutoPack" + PackConfig[index].name +"_" + versionStr + "_" + PackTime + ".apk'" + printlog,
"git push",
};
ProcessUtil.ProcessCommand(_MomPackPath + PackConfig[index].project, commands);
EditorUtility.ClearProgressBar();
}
}
//private static void ExportXcode(string _sceneName)
//{
// PlayerSettings.productName = "太初行";
// string mainXcodePath =
// isZs? "/Volumes/ELEMENTS/JieLing/Packager/IOS/MHT_HW_RELEASE": "/Volumes/ELEMENTS/JieLing/Packager/IOS/MHT_HW_TEST";
// string outPath = isZs?"/Volumes/ELEMENTS/JieLing/Packager/IOS/exXcodePro_Release":"/Volumes/ELEMENTS/JieLing/Packager/IOS/exXcodePro_Test";
// if (Directory.Exists(outPath))
// {
// Directory.Delete(outPath, true);
// }
// // 设置需要打包的场景
// string launchScene = _sceneName;
// Debug.Log("打包场景:" + launchScene);
// BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions();
// buildPlayerOptions.locationPathName = outPath;
// buildPlayerOptions.options = BuildOptions.None;
// buildPlayerOptions.options |= BuildOptions.AcceptExternalModificationsToPlayer;
// buildPlayerOptions.scenes = new[] { launchScene };
// buildPlayerOptions.target = BuildTarget.iOS;
// // 调用开始打包
// BuildPipeline.BuildPlayer(buildPlayerOptions);
// Debug.Log("打包完成");
// Debug.Log("导出工程路径:"+ outPath);
// if (Directory.Exists(mainXcodePath)&& Directory.Exists(outPath))
// {
// Debug.Log("替换xcode资源");
// Directory.Delete(mainXcodePath+"/Data", true);
// Directory.Move(outPath+"/Data",mainXcodePath+"/Data");
// Directory.Delete(mainXcodePath+"/Classes/Native", true);
// Directory.Move(outPath+"/Classes/Native",mainXcodePath+"/Classes/Native");
// }
//}
}