You've already forked Commercialization.topon
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f0a21e33ec | |||
| aba204a310 |
15
CHANGELOG.md
15
CHANGELOG.md
@@ -1,3 +1,18 @@
|
||||
# [1.4.14]
|
||||
|
||||
### 修复
|
||||
|
||||
* Release 默认不再通过 EDM4U 声明 `com.anythink.sdk:debugger-ui:+`,避免 `com.verbto.tools:util:1.0.6` 进入正式包触发 `anr_data.db` 降级崩溃。
|
||||
* 新增 `TopOn 配置` 构建页签,可按构建配置启用 DebugUI;关闭时构建后处理会从生成的 Gradle 工程剔除 `debugger-ui` 和 `verbto util`。
|
||||
* 启用 DebugUI 时同步声明 `com.verbto.tools:util:1.1.3` 作为诊断库兜底版本。
|
||||
|
||||
# [1.4.13]
|
||||
|
||||
### 修复
|
||||
|
||||
* 移除包内嵌的 EDM4U 1.2.177,避免消费项目启动导入阶段重复初始化 Google Version Handler 并写入 `ProjectSettings/GvhProjectSettings.xml`。
|
||||
* 保留 `Dependencies.xml` 依赖声明,由宿主项目统一安装和管理 EDM4U 版本。
|
||||
|
||||
# [1.4.12]
|
||||
|
||||
### 修复
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 90c597385ff9346a89d38256315fb735
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 773d3f2446f5440bb892ec25e114d547
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9ee3e98fba8c1468bbdf8cfa0803a7d8
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -1,36 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5552c54c11d94016bcfe740f27df44a6
|
||||
labels:
|
||||
- gvh
|
||||
- gvh_version-1.2.177
|
||||
- gvhp_exportpath-ExternalDependencyManager/Editor/1.2.177/Google.IOSResolver.dll
|
||||
- gvhp_targets-editor
|
||||
timeCreated: 1480838400
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
Windows Store Apps: WindowsStoreApps
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -1,36 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1f4f113972f04c3695341dfb3ba48d3b
|
||||
labels:
|
||||
- gvh
|
||||
- gvh_version-1.2.177
|
||||
- gvhp_exportpath-ExternalDependencyManager/Editor/1.2.177/Google.JarResolver.dll
|
||||
- gvhp_targets-editor
|
||||
timeCreated: 1480838400
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
Windows Store Apps: WindowsStoreApps
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -1,36 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 413ed4abd14645c38ebbd8c5ff26e9de
|
||||
labels:
|
||||
- gvh
|
||||
- gvh_version-1.2.177
|
||||
- gvhp_exportpath-ExternalDependencyManager/Editor/1.2.177/Google.PackageManagerResolver.dll
|
||||
- gvhp_targets-editor
|
||||
timeCreated: 1480838400
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
Windows Store Apps: WindowsStoreApps
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -1,36 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 38d0b40a7b2d44c6a6a2362599bfc41e
|
||||
labels:
|
||||
- gvh
|
||||
- gvh_version-1.2.177
|
||||
- gvhp_exportpath-ExternalDependencyManager/Editor/1.2.177/Google.VersionHandlerImpl.dll
|
||||
- gvhp_targets-editor
|
||||
timeCreated: 1480838400
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
Windows Store Apps: WindowsStoreApps
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -1,36 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86460262ea60447dbb6a62d21167790f
|
||||
labels:
|
||||
- gvh
|
||||
- gvh_version-1.2.177
|
||||
- gvhp_exportpath-ExternalDependencyManager/Editor/Google.VersionHandler.dll
|
||||
- gvhp_targets-editor
|
||||
timeCreated: 1480838400
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
Windows Store Apps: WindowsStoreApps
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,13 +0,0 @@
|
||||
Assets/ExternalDependencyManager/Editor/1.2.177/Google.IOSResolver.dll
|
||||
Assets/ExternalDependencyManager/Editor/1.2.177/Google.IOSResolver.dll.mdb
|
||||
Assets/ExternalDependencyManager/Editor/1.2.177/Google.JarResolver.dll
|
||||
Assets/ExternalDependencyManager/Editor/1.2.177/Google.JarResolver.dll.mdb
|
||||
Assets/ExternalDependencyManager/Editor/1.2.177/Google.PackageManagerResolver.dll
|
||||
Assets/ExternalDependencyManager/Editor/1.2.177/Google.PackageManagerResolver.dll.mdb
|
||||
Assets/ExternalDependencyManager/Editor/1.2.177/Google.VersionHandlerImpl.dll
|
||||
Assets/ExternalDependencyManager/Editor/1.2.177/Google.VersionHandlerImpl.dll.mdb
|
||||
Assets/ExternalDependencyManager/Editor/CHANGELOG.md
|
||||
Assets/ExternalDependencyManager/Editor/Google.VersionHandler.dll
|
||||
Assets/ExternalDependencyManager/Editor/Google.VersionHandler.dll.mdb
|
||||
Assets/ExternalDependencyManager/Editor/LICENSE
|
||||
Assets/ExternalDependencyManager/Editor/README.md
|
||||
@@ -1,15 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2764c5ea3b354f3cb7ca80028fd08da2
|
||||
labels:
|
||||
- gvh
|
||||
- gvh_manifest
|
||||
- gvh_version-1.2.177
|
||||
- gvhp_exportpath-ExternalDependencyManager/Editor/external-dependency-manager_version-1.2.177_manifest.txt
|
||||
- gvhp_manifestname-0External Dependency Manager
|
||||
- gvhp_manifestname-play-services-resolver
|
||||
timeCreated: 1474401009
|
||||
licenseType: Pro
|
||||
TextScriptImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,245 @@
|
||||
#if UNITY_ANDROID
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using UnityEditor.Android;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Topon_Adapter.Editor
|
||||
{
|
||||
public sealed class ToponAndroidDebuggerDependencyPostProcessor : IPostGenerateGradleAndroidProject
|
||||
{
|
||||
private const string Tag = "[TopOn Build]";
|
||||
private const string DebuggerDependency = "com.anythink.sdk:debugger-ui:+";
|
||||
private const string VerbtoDependency = "com.verbto.tools:util:1.1.3";
|
||||
private const string DebuggerRepositoryUrl = "https://jfrog.anythinktech.com/artifactory/debugger";
|
||||
private const string DepsStart = "// TopOn Debugger UI Dependencies Start";
|
||||
private const string DepsEnd = "// TopOn Debugger UI Dependencies End";
|
||||
private const string ReposStart = "// TopOn Debugger UI Repository Start";
|
||||
private const string ReposEnd = "// TopOn Debugger UI Repository End";
|
||||
|
||||
public int callbackOrder => int.MaxValue;
|
||||
|
||||
public void OnPostGenerateGradleAndroidProject(string path)
|
||||
{
|
||||
var settings = ToponBuildSettingsStore.GetActiveForCurrentBuild();
|
||||
try
|
||||
{
|
||||
ProcessGeneratedProject(path, settings);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ToponBuildSettingsStore.ClearActiveBuildSettings();
|
||||
}
|
||||
}
|
||||
|
||||
public static void ProcessGeneratedProject(string path, ToponBuildSettings settings)
|
||||
{
|
||||
if (settings == null)
|
||||
{
|
||||
settings = ToponBuildSettingsStore.CreateDefault();
|
||||
}
|
||||
|
||||
var gradleRoot = GetGradleRoot(path);
|
||||
var gradleFiles = new[]
|
||||
{
|
||||
Path.Combine(path, "build.gradle"),
|
||||
Path.Combine(gradleRoot, "launcher", "build.gradle"),
|
||||
Path.Combine(gradleRoot, "build.gradle")
|
||||
};
|
||||
|
||||
foreach (var gradleFile in gradleFiles)
|
||||
{
|
||||
StripDebuggerFromGradleFile(gradleFile);
|
||||
}
|
||||
|
||||
StripDebuggerFromGradleFile(Path.Combine(gradleRoot, "settings.gradle"));
|
||||
|
||||
if (settings.enableDebuggerUI)
|
||||
{
|
||||
InjectRepository(Path.Combine(gradleRoot, "settings.gradle"));
|
||||
InjectRepository(Path.Combine(gradleRoot, "build.gradle"));
|
||||
InjectDependencies(Path.Combine(path, "build.gradle"), settings.forceVerbtoUtilVersion);
|
||||
Debug.Log($"{Tag} DebugUI dependency enabled for this build.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (settings.stripResolvedDebuggerArtifacts)
|
||||
{
|
||||
RemoveGeneratedDebuggerArtifacts(gradleRoot);
|
||||
}
|
||||
|
||||
Debug.Log($"{Tag} DebugUI dependency disabled for this build.");
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetGradleRoot(string unityLibraryPath)
|
||||
{
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
return Path.GetFullPath(Path.Combine(unityLibraryPath, ".."));
|
||||
#else
|
||||
return Path.GetFullPath(unityLibraryPath);
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void StripDebuggerFromGradleFile(string filePath)
|
||||
{
|
||||
if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var content = File.ReadAllText(filePath);
|
||||
var original = content;
|
||||
content = RemoveMarkedBlock(content, DepsStart, DepsEnd);
|
||||
content = RemoveMarkedBlock(content, ReposStart, ReposEnd);
|
||||
content = RemoveDebuggerRepositoryBlocks(content);
|
||||
content = RemoveLinesContaining(content, "com.anythink.sdk:debugger-ui", "com.verbto.tools:util");
|
||||
|
||||
if (!string.Equals(original, content, StringComparison.Ordinal))
|
||||
{
|
||||
File.WriteAllText(filePath, content);
|
||||
}
|
||||
}
|
||||
|
||||
private static void InjectDependencies(string buildGradlePath, bool forceVerbtoUtilVersion)
|
||||
{
|
||||
if (!File.Exists(buildGradlePath))
|
||||
{
|
||||
Debug.LogWarning($"{Tag} build.gradle not found: {buildGradlePath}");
|
||||
return;
|
||||
}
|
||||
|
||||
var content = File.ReadAllText(buildGradlePath);
|
||||
var block = new StringBuilder();
|
||||
block.AppendLine(DepsStart);
|
||||
block.AppendLine($" implementation '{DebuggerDependency}'");
|
||||
if (forceVerbtoUtilVersion)
|
||||
{
|
||||
block.AppendLine($" implementation '{VerbtoDependency}'");
|
||||
}
|
||||
|
||||
block.AppendLine($" {DepsEnd}");
|
||||
|
||||
var pattern = new Regex(@"(dependencies\s*\{)");
|
||||
if (!pattern.IsMatch(content))
|
||||
{
|
||||
Debug.LogWarning($"{Tag} dependencies block not found: {buildGradlePath}");
|
||||
return;
|
||||
}
|
||||
|
||||
content = pattern.Replace(content, match => match.Groups[1].Value + "\n " + block, 1);
|
||||
File.WriteAllText(buildGradlePath, content);
|
||||
}
|
||||
|
||||
private static void InjectRepository(string gradlePath)
|
||||
{
|
||||
if (!File.Exists(gradlePath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var content = File.ReadAllText(gradlePath);
|
||||
var block = $"{ReposStart}\n maven {{ url '{DebuggerRepositoryUrl}' }}\n {ReposEnd}";
|
||||
Regex pattern;
|
||||
if (Path.GetFileName(gradlePath).Equals("settings.gradle", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
pattern = new Regex(@"(dependencyResolutionManagement\s*\{[\s\S]*?repositories\s*\{)");
|
||||
}
|
||||
else
|
||||
{
|
||||
block = $"{ReposStart}\n maven {{ url '{DebuggerRepositoryUrl}' }}\n {ReposEnd}";
|
||||
pattern = new Regex(@"(repositories\s*\{)");
|
||||
}
|
||||
|
||||
if (!pattern.IsMatch(content))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
content = pattern.Replace(content, match => match.Groups[1].Value + "\n " + block, 1);
|
||||
File.WriteAllText(gradlePath, content);
|
||||
}
|
||||
|
||||
private static void RemoveGeneratedDebuggerArtifacts(string gradleRoot)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(gradleRoot) || !Directory.Exists(gradleRoot))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var root = Path.GetFullPath(gradleRoot).TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
|
||||
foreach (var path in Directory.GetFiles(root, "*", SearchOption.AllDirectories))
|
||||
{
|
||||
if (!ToponBuildSettingsStore.IsDebuggerArtifactFileName(Path.GetFileName(path)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var fullPath = Path.GetFullPath(path);
|
||||
if (!fullPath.StartsWith(root, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
File.Delete(fullPath);
|
||||
Debug.Log($"{Tag} Removed generated debugger artifact: {fullPath}");
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Debug.LogWarning($"{Tag} Failed to remove generated debugger artifact: {exception.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string RemoveMarkedBlock(string content, string startMarker, string endMarker)
|
||||
{
|
||||
var pattern = new Regex($@"\s*{Regex.Escape(startMarker)}[\s\S]*?{Regex.Escape(endMarker)}\s*");
|
||||
return pattern.Replace(content, "\n");
|
||||
}
|
||||
|
||||
private static string RemoveDebuggerRepositoryBlocks(string content)
|
||||
{
|
||||
var escapedUrl = Regex.Escape(DebuggerRepositoryUrl);
|
||||
content = Regex.Replace(
|
||||
content,
|
||||
$@"\r?\n\s*maven\s*\{{\s*url\s*['""]{escapedUrl}['""][^\r\n]*\s*\}}",
|
||||
string.Empty);
|
||||
content = Regex.Replace(
|
||||
content,
|
||||
$@"\r?\n\s*maven\s*\{{\s*\r?\n\s*url\s*['""]{escapedUrl}['""][^\r\n]*\r?\n\s*\}}",
|
||||
string.Empty);
|
||||
return content;
|
||||
}
|
||||
|
||||
private static string RemoveLinesContaining(string content, params string[] markers)
|
||||
{
|
||||
var lines = content.Replace("\r\n", "\n").Replace('\r', '\n').Split('\n');
|
||||
var kept = new List<string>();
|
||||
foreach (var line in lines)
|
||||
{
|
||||
var remove = false;
|
||||
foreach (var marker in markers)
|
||||
{
|
||||
if (line.Contains(marker))
|
||||
{
|
||||
remove = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!remove)
|
||||
{
|
||||
kept.Add(line);
|
||||
}
|
||||
}
|
||||
|
||||
return string.Join("\n", kept);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5a10306d60f749a28af78c8c54738cd8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
266
Topon_Adapter/Editor/ToponBuildSettingsStore.cs
Normal file
266
Topon_Adapter/Editor/ToponBuildSettingsStore.cs
Normal file
@@ -0,0 +1,266 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Topon_Adapter.Editor
|
||||
{
|
||||
[Serializable]
|
||||
public sealed class ToponBuildSettings
|
||||
{
|
||||
public bool enableDebuggerUI = false;
|
||||
public bool forceVerbtoUtilVersion = true;
|
||||
public bool stripResolvedDebuggerArtifacts = true;
|
||||
}
|
||||
|
||||
internal static class ToponBuildSettingsStore
|
||||
{
|
||||
private const string ActiveBuildSessionKey = "Commercialization.Topon.ActiveBuildSettings";
|
||||
private const string SettingsFileSuffix = "_topon_build_settings.json";
|
||||
private const string BuildConfigsFolder = "BuildConfigs";
|
||||
private const string DebuggerPackageMarker = "com.anythink.sdk:debugger-ui";
|
||||
private const string VerbtoPackageMarker = "com.verbto.tools:util";
|
||||
private const string DebuggerRepositoryMarker = "jfrog.anythinktech.com/artifactory/debugger";
|
||||
|
||||
[Serializable]
|
||||
private sealed class ActiveBuildSettings
|
||||
{
|
||||
public ToponBuildSettings settings;
|
||||
public long utcTicks;
|
||||
}
|
||||
|
||||
public static ToponBuildSettings CreateDefault()
|
||||
{
|
||||
return new ToponBuildSettings();
|
||||
}
|
||||
|
||||
public static ToponBuildSettings LoadForProfileName(string profileName, string repositoryRoot)
|
||||
{
|
||||
var settings = CreateDefault();
|
||||
var path = GetSettingsPath(profileName, repositoryRoot);
|
||||
if (string.IsNullOrEmpty(path) || !File.Exists(path))
|
||||
{
|
||||
return settings;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
JsonUtility.FromJsonOverwrite(File.ReadAllText(path), settings);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Debug.LogWarning($"[TopOn Build] Failed to read build settings: {exception.Message}");
|
||||
}
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
public static void SaveForProfileName(string profileName, string repositoryRoot, ToponBuildSettings settings)
|
||||
{
|
||||
if (settings == null)
|
||||
{
|
||||
settings = CreateDefault();
|
||||
}
|
||||
|
||||
var path = GetSettingsPath(profileName, repositoryRoot);
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var directory = Path.GetDirectoryName(path);
|
||||
if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
|
||||
{
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
|
||||
File.WriteAllText(path, JsonUtility.ToJson(settings, true));
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Debug.LogWarning($"[TopOn Build] Failed to save build settings: {exception.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetActiveForCurrentBuild(ToponBuildSettings settings)
|
||||
{
|
||||
var activeSettings = new ActiveBuildSettings
|
||||
{
|
||||
settings = Clone(settings),
|
||||
utcTicks = DateTime.UtcNow.Ticks
|
||||
};
|
||||
|
||||
SessionState.SetString(ActiveBuildSessionKey, JsonUtility.ToJson(activeSettings));
|
||||
}
|
||||
|
||||
public static ToponBuildSettings GetActiveForCurrentBuild()
|
||||
{
|
||||
var json = SessionState.GetString(ActiveBuildSessionKey, string.Empty);
|
||||
if (string.IsNullOrWhiteSpace(json))
|
||||
{
|
||||
return CreateDefault();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var activeSettings = JsonUtility.FromJson<ActiveBuildSettings>(json);
|
||||
if (activeSettings == null || activeSettings.settings == null)
|
||||
{
|
||||
return CreateDefault();
|
||||
}
|
||||
|
||||
var activatedAt = new DateTime(activeSettings.utcTicks, DateTimeKind.Utc);
|
||||
if (DateTime.UtcNow - activatedAt > TimeSpan.FromHours(6))
|
||||
{
|
||||
ClearActiveBuildSettings();
|
||||
return CreateDefault();
|
||||
}
|
||||
|
||||
return Clone(activeSettings.settings);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Debug.LogWarning($"[TopOn Build] Failed to read active build settings: {exception.Message}");
|
||||
return CreateDefault();
|
||||
}
|
||||
}
|
||||
|
||||
public static void ClearActiveBuildSettings()
|
||||
{
|
||||
SessionState.EraseString(ActiveBuildSessionKey);
|
||||
}
|
||||
|
||||
public static bool HasStaleDebuggerResolverOutput(string repositoryRoot)
|
||||
{
|
||||
foreach (var path in GetResolverOutputPaths(repositoryRoot))
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var content = File.ReadAllText(path);
|
||||
if (content.Contains(DebuggerPackageMarker) ||
|
||||
content.Contains(VerbtoPackageMarker) ||
|
||||
content.Contains(DebuggerRepositoryMarker))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static IReadOnlyList<string> FindResolvedDebuggerArtifacts(string repositoryRoot)
|
||||
{
|
||||
var result = new List<string>();
|
||||
var root = ResolveRepositoryRoot(repositoryRoot);
|
||||
if (string.IsNullOrEmpty(root))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
var androidPluginPath = Path.Combine(root, "Assets", "Plugins", "Android");
|
||||
if (!Directory.Exists(androidPluginPath))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
foreach (var path in Directory.GetFiles(androidPluginPath, "*", SearchOption.AllDirectories))
|
||||
{
|
||||
if (IsDebuggerArtifactFileName(Path.GetFileName(path)))
|
||||
{
|
||||
result.Add(path);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static bool IsDebuggerArtifactFileName(string fileName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(fileName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return fileName.StartsWith("com.anythink.sdk.debugger-ui-", StringComparison.OrdinalIgnoreCase) ||
|
||||
fileName.StartsWith("com.verbto.tools.util-", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private static ToponBuildSettings Clone(ToponBuildSettings settings)
|
||||
{
|
||||
if (settings == null)
|
||||
{
|
||||
return CreateDefault();
|
||||
}
|
||||
|
||||
return new ToponBuildSettings
|
||||
{
|
||||
enableDebuggerUI = settings.enableDebuggerUI,
|
||||
forceVerbtoUtilVersion = settings.forceVerbtoUtilVersion,
|
||||
stripResolvedDebuggerArtifacts = settings.stripResolvedDebuggerArtifacts
|
||||
};
|
||||
}
|
||||
|
||||
private static IEnumerable<string> GetResolverOutputPaths(string repositoryRoot)
|
||||
{
|
||||
var root = ResolveRepositoryRoot(repositoryRoot);
|
||||
if (string.IsNullOrEmpty(root))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
yield return Path.Combine(root, "ProjectSettings", "AndroidResolverDependencies.xml");
|
||||
yield return Path.Combine(root, "Assets", "Plugins", "Android", "mainTemplate.gradle");
|
||||
yield return Path.Combine(root, "Assets", "Plugins", "Android", "mainTemplate.gradle.backup");
|
||||
yield return Path.Combine(root, "Assets", "Plugins", "Android", "settingsTemplate.gradle");
|
||||
}
|
||||
|
||||
private static string GetSettingsPath(string profileName, string repositoryRoot)
|
||||
{
|
||||
var root = ResolveRepositoryRoot(repositoryRoot);
|
||||
if (string.IsNullOrEmpty(root))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return Path.Combine(root, BuildConfigsFolder, $"{SanitizeProfileName(profileName)}{SettingsFileSuffix}");
|
||||
}
|
||||
|
||||
private static string ResolveRepositoryRoot(string repositoryRoot)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(repositoryRoot))
|
||||
{
|
||||
return Path.GetFullPath(repositoryRoot);
|
||||
}
|
||||
|
||||
var dataPath = Application.dataPath;
|
||||
var parent = Directory.GetParent(dataPath);
|
||||
return parent == null ? string.Empty : parent.FullName;
|
||||
}
|
||||
|
||||
private static string SanitizeProfileName(string profileName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(profileName))
|
||||
{
|
||||
return "default";
|
||||
}
|
||||
|
||||
var invalidChars = Path.GetInvalidFileNameChars();
|
||||
var chars = profileName.ToCharArray();
|
||||
for (var i = 0; i < chars.Length; i++)
|
||||
{
|
||||
if (Array.IndexOf(invalidChars, chars[i]) >= 0)
|
||||
{
|
||||
chars[i] = '_';
|
||||
}
|
||||
}
|
||||
|
||||
return new string(chars);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Topon_Adapter/Editor/ToponBuildSettingsStore.cs.meta
Normal file
11
Topon_Adapter/Editor/ToponBuildSettingsStore.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 47b497e660b24e94b8e09d600f9c0fb8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
120
Topon_Adapter/Editor/ToponBuildWindowExtension.cs
Normal file
120
Topon_Adapter/Editor/ToponBuildWindowExtension.cs
Normal file
@@ -0,0 +1,120 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Topon_Adapter.Editor
|
||||
{
|
||||
[InitializeOnLoad]
|
||||
internal static class ToponBuildWindowExtensionBootstrap
|
||||
{
|
||||
static ToponBuildWindowExtensionBootstrap()
|
||||
{
|
||||
BuildWindowExtensionRegistry.Register(new ToponBuildWindowExtension());
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ToponBuildWindowExtension : IBuildWindowExtension
|
||||
{
|
||||
public string Id => "com.commercialization.topon.build.settings";
|
||||
public string DisplayName => "TopOn 配置";
|
||||
public int Order => 80;
|
||||
|
||||
public void DrawSection(BuildWindowExtensionContext context)
|
||||
{
|
||||
var profile = context?.profile;
|
||||
if (profile == null)
|
||||
{
|
||||
EditorGUILayout.HelpBox("当前没有构建配置。", MessageType.Info);
|
||||
return;
|
||||
}
|
||||
|
||||
var settings = ToponBuildSettingsStore.LoadForProfileName(profile.profileName, context.repositoryRoot);
|
||||
|
||||
EditorGUILayout.LabelField("TopOn Android 调试工具", EditorStyles.boldLabel);
|
||||
EditorGUILayout.HelpBox(
|
||||
"正式 release 默认关闭 DebugUI。关闭后构建后处理会剔除 debugger-ui 及其诊断库,避免 anr_data.db 降级崩溃。",
|
||||
MessageType.Info);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
settings.enableDebuggerUI = EditorGUILayout.Toggle(
|
||||
new GUIContent("启用 DebugUI 依赖", "仅用于开发/测试包;正式 release 应保持关闭。"),
|
||||
settings.enableDebuggerUI);
|
||||
|
||||
using (new EditorGUI.DisabledScope(!settings.enableDebuggerUI))
|
||||
{
|
||||
settings.forceVerbtoUtilVersion = EditorGUILayout.Toggle(
|
||||
new GUIContent("强制 util 1.1.3", "启用 DebugUI 时同时声明 com.verbto.tools:util:1.1.3,避免回落到 1.0.6。"),
|
||||
settings.forceVerbtoUtilVersion);
|
||||
}
|
||||
|
||||
settings.stripResolvedDebuggerArtifacts = EditorGUILayout.Toggle(
|
||||
new GUIContent("禁用时剔除旧产物", "关闭 DebugUI 时,从生成的 Gradle 工程中删除旧 Resolver 带入的 debugger-ui/util AAR。"),
|
||||
settings.stripResolvedDebuggerArtifacts);
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
ToponBuildSettingsStore.SaveForProfileName(profile.profileName, context.repositoryRoot, settings);
|
||||
}
|
||||
|
||||
EditorGUILayout.Space(6);
|
||||
if (settings.enableDebuggerUI)
|
||||
{
|
||||
EditorGUILayout.HelpBox("当前配置会把 TopOn DebugUI 打进 Android 构建;请不要用于正式 release。", MessageType.Warning);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.HelpBox("当前配置不会打包 TopOn DebugUI。", MessageType.None);
|
||||
}
|
||||
|
||||
DrawResolverStatus(context);
|
||||
}
|
||||
|
||||
public BuildWindowExtensionReport Preflight(BuildWindowExtensionContext context)
|
||||
{
|
||||
var profile = context?.profile;
|
||||
if (profile == null)
|
||||
{
|
||||
return BuildWindowExtensionReport.Pass();
|
||||
}
|
||||
|
||||
var settings = ToponBuildSettingsStore.LoadForProfileName(profile.profileName, context.repositoryRoot);
|
||||
ToponBuildSettingsStore.SetActiveForCurrentBuild(settings);
|
||||
|
||||
var report = BuildWindowExtensionReport.Pass();
|
||||
if (settings.enableDebuggerUI)
|
||||
{
|
||||
report.AddMessage("TopOn DebugUI 已启用。");
|
||||
if (!profile.isDevelopment)
|
||||
{
|
||||
report.AddWarning("当前不是 Development Build,请确认该配置不是正式 release。");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
report.AddMessage("TopOn DebugUI 已关闭,构建产物会剔除 debugger-ui/util 诊断库。");
|
||||
}
|
||||
|
||||
if (!settings.enableDebuggerUI && ToponBuildSettingsStore.HasStaleDebuggerResolverOutput(context.repositoryRoot))
|
||||
{
|
||||
report.AddWarning("检测到旧 Resolver 输出仍包含 TopOn DebugUI;本次构建会在生成 Gradle 后剔除,建议后续重新 Resolve。");
|
||||
}
|
||||
|
||||
return report;
|
||||
}
|
||||
|
||||
public BuildWindowExtensionReport PostBuild(BuildWindowExtensionContext context)
|
||||
{
|
||||
return BuildWindowExtensionReport.Pass();
|
||||
}
|
||||
|
||||
private static void DrawResolverStatus(BuildWindowExtensionContext context)
|
||||
{
|
||||
var hasStaleOutput = ToponBuildSettingsStore.HasStaleDebuggerResolverOutput(context.repositoryRoot);
|
||||
var artifacts = ToponBuildSettingsStore.FindResolvedDebuggerArtifacts(context.repositoryRoot);
|
||||
|
||||
EditorGUILayout.Space(6);
|
||||
EditorGUILayout.LabelField("本地依赖状态", EditorStyles.boldLabel);
|
||||
EditorGUILayout.LabelField("旧 Resolver 输出", hasStaleOutput ? "检测到 debugger-ui/util" : "未检测到");
|
||||
EditorGUILayout.LabelField("已解析 AAR/JAR", artifacts.Count == 0 ? "未检测到" : $"{artifacts.Count} 个");
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Topon_Adapter/Editor/ToponBuildWindowExtension.cs.meta
Normal file
11
Topon_Adapter/Editor/ToponBuildWindowExtension.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 59588e94a9074edba04bd828d233dd25
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,9 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<dependencies>
|
||||
<androidPackages>
|
||||
<repositories>
|
||||
<repository>https://jfrog.anythinktech.com/artifactory/debugger</repository>
|
||||
</repositories>
|
||||
<androidPackage spec="com.anythink.sdk:debugger-ui:+"/>
|
||||
<!-- Debugger UI is injected by Topon build settings only when explicitly enabled. -->
|
||||
</androidPackages>
|
||||
</dependencies>
|
||||
</dependencies>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"GUID:8a3d1447e0a3bdf4fa07035516da8b62",
|
||||
"GUID:3198a86b02613024e960e3d04a9638cd",
|
||||
"GUID:483a01338fa974b4498cd71261d6e8b9",
|
||||
"GUID:87bccae0237fd4a41ac446d6636f95e0"
|
||||
"GUID:24277cc3923ff5f49b48e1a274d4a02b"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "com.commercialization.topon",
|
||||
"displayName": "Commercialization.topon",
|
||||
"description": "基于topon的广告sdk封装,依赖基础商业化模块",
|
||||
"version": "1.4.12",
|
||||
"version": "1.4.14",
|
||||
"unity": "2021.1",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
|
||||
Reference in New Issue
Block a user