Files
Commercialization.tapadn/Assets/DirichletMediation/Editor/DirichletGradlePostProcessor.cs

273 lines
12 KiB
C#
Raw Normal View History

#if UNITY_ANDROID
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEditor.Android;
using UnityEngine;
namespace Dirichlet.Mediation.Editor
{
/// <summary>
/// Post-processes the Gradle files to inject Dirichlet SDK dependencies.
///
/// This approach allows coexistence with other SDKs (e.g., TapSDK) by injecting
/// dependencies into Unity-generated Gradle files rather than shipping static templates.
/// </summary>
public class DirichletGradlePostProcessor : IPostGenerateGradleAndroidProject
{
private const string TAG = "[DirichletMediation]";
// Marker comments to identify our injected content
private const string DIRICHLET_DEPS_START = "// Dirichlet Mediation Dependencies Start";
private const string DIRICHLET_DEPS_END = "// Dirichlet Mediation Dependencies End";
private const string DIRICHLET_REPOS_START = "// Dirichlet Mediation Repositories Start";
private const string DIRICHLET_REPOS_END = "// Dirichlet Mediation Repositories End";
public int callbackOrder => 100; // Run after EDM4U (which uses lower values)
public void OnPostGenerateGradleAndroidProject(string path)
{
var enableCsj = EditorPrefs.GetBool("Dirichlet.Android.EnableCSJ", true);
var enableGdt = EditorPrefs.GetBool("Dirichlet.Android.EnableGDT", true);
var enableIqy = EditorPrefs.GetBool("Dirichlet.Android.EnableIQY", true);
Debug.Log($"{TAG} Processing Gradle project at: {path}");
Debug.Log($"{TAG} CSJ enabled: {enableCsj}, GDT enabled: {enableGdt}, IQY enabled: {enableIqy}");
ProcessBuildGradle(path, enableCsj, enableGdt, enableIqy);
ProcessSettingsGradle(path, enableCsj, enableGdt, enableIqy);
}
private void ProcessBuildGradle(string projectPath, bool enableCsj, bool enableGdt, bool enableIqy)
{
// Unity 2019.3+: projectPath is unityLibrary folder, build.gradle is directly inside
// Unity 2019.2 and below: projectPath might be the root, need to search
var gradlePath = Path.Combine(projectPath, "build.gradle");
if (!File.Exists(gradlePath))
{
// Fallback: try to find build.gradle in subdirectories
var searchPaths = new[]
{
Path.Combine(projectPath, "unityLibrary", "build.gradle"),
Path.Combine(projectPath, "src", "main", "build.gradle")
};
foreach (var path in searchPaths)
{
if (File.Exists(path))
{
gradlePath = path;
break;
}
}
}
if (!File.Exists(gradlePath))
{
Debug.LogWarning($"{TAG} Could not find build.gradle at {projectPath}");
return;
}
Debug.Log($"{TAG} Found build.gradle at: {gradlePath}");
var content = File.ReadAllText(gradlePath);
Debug.Log($"{TAG} Original build.gradle length: {content.Length}");
// Remove any previously injected content (for clean re-injection)
content = RemoveInjectedContent(content, DIRICHLET_DEPS_START, DIRICHLET_DEPS_END);
content = RemoveInjectedContent(content, DIRICHLET_REPOS_START, DIRICHLET_REPOS_END);
// Inject repositories
content = InjectRepositories(content, enableCsj, enableGdt, enableIqy);
// Inject dependencies
content = InjectDependencies(content, enableCsj, enableGdt, enableIqy);
File.WriteAllText(gradlePath, content);
Debug.Log($"{TAG} Updated build.gradle with Dirichlet Mediation dependencies");
}
private string InjectRepositories(string content, bool enableCsj, bool enableGdt, bool enableIqy)
{
// Check if our repos are already injected
if (content.Contains(DIRICHLET_REPOS_START))
{
return content;
}
var reposBlock = new StringBuilder();
reposBlock.AppendLine(DIRICHLET_REPOS_START);
reposBlock.AppendLine(" google()");
reposBlock.AppendLine(" mavenCentral()");
reposBlock.AppendLine(" flatDir {");
reposBlock.AppendLine(" dirs 'libs', 'DirichletMediation/libs'");
reposBlock.AppendLine(" }");
if (enableCsj)
{
reposBlock.AppendLine(" maven { url 'https://artifact.bytedance.com/repository/pangle' }");
}
if (enableGdt)
{
reposBlock.AppendLine(" maven { url 'https://mirrors.tencent.com/nexus/repository/maven-public/' }");
}
reposBlock.AppendLine($" {DIRICHLET_REPOS_END}");
// Try to find repositories block and inject after opening brace
var reposPattern = new Regex(@"(repositories\s*\{)");
if (reposPattern.IsMatch(content))
{
content = reposPattern.Replace(content, m =>
m.Groups[1].Value + "\n " + reposBlock.ToString(), 1);
Debug.Log($"{TAG} Injected repositories block");
}
else
{
Debug.LogWarning($"{TAG} Could not find repositories block, adding one");
var applyPattern = new Regex(@"(apply plugin:\s*'com\.android\.library'[^\n]*\n)");
if (applyPattern.IsMatch(content))
{
content = applyPattern.Replace(content, m =>
m.Groups[1].Value + "\nrepositories {\n " + reposBlock.ToString() + "}\n", 1);
}
}
return content;
}
private string InjectDependencies(string content, bool enableCsj, bool enableGdt, bool enableIqy)
{
// Check if our deps are already injected
if (content.Contains(DIRICHLET_DEPS_START))
{
return content;
}
var depsBlock = new StringBuilder();
depsBlock.AppendLine(DIRICHLET_DEPS_START);
// Core Mediation AAR
depsBlock.AppendLine(" implementation(name: 'DirichletAD_Mediation_4.2.5.0', ext: 'aar')");
// CSJ (穿山甲) Adapter and SDK
if (enableCsj)
{
depsBlock.AppendLine(" implementation(name: 'DirichletAD_CSJ_Adapter_4.2.5.0', ext: 'aar')");
depsBlock.AppendLine(" implementation(name: 'open_ad_sdk_7.4.2.2', ext: 'aar')");
}
// GDT (广点通) Adapter and SDK
if (enableGdt)
{
depsBlock.AppendLine(" implementation(name: 'DirichletAD_GDT_Adapter_4.2.5.0', ext: 'aar')");
depsBlock.AppendLine(" implementation(name: 'GDTSDK.unionNormal.4.671.1541', ext: 'aar')");
}
// IQY (爱奇艺) Adapter and SDK
if (enableIqy)
{
depsBlock.AppendLine(" implementation(name: 'DirichletAD_IQY_Adapter_4.2.5.0', ext: 'aar')");
depsBlock.AppendLine(" implementation(name: 'iadsdk-release-2.3.102.110', ext: 'aar')");
depsBlock.AppendLine(" implementation 'com.android.support.constraint:constraint-layout:1.1.3'");
}
// Maven dependencies (required for SDK functionality)
depsBlock.AppendLine(" implementation 'com.android.support:recyclerview-v7:28.0.0'");
depsBlock.AppendLine(" implementation 'com.github.bumptech.glide:glide:4.9.0'");
depsBlock.AppendLine(" implementation 'com.android.support:support-v4:28.0.0'");
depsBlock.AppendLine(" implementation 'com.android.support:support-annotations:28.0.0'");
depsBlock.AppendLine(" implementation 'com.android.support:appcompat-v7:28.0.0'");
depsBlock.AppendLine(" implementation 'com.squareup.okhttp3:okhttp:3.12.1'");
depsBlock.AppendLine($" {DIRICHLET_DEPS_END}");
// Find dependencies block and inject after opening brace
var depsPattern = new Regex(@"(dependencies\s*\{)");
if (depsPattern.IsMatch(content))
{
content = depsPattern.Replace(content, m =>
m.Groups[1].Value + "\n " + depsBlock.ToString(), 1);
Debug.Log($"{TAG} Injected dependencies block");
}
else
{
Debug.LogWarning($"{TAG} Could not find dependencies block");
}
return content;
}
private void ProcessSettingsGradle(string projectPath, bool enableCsj, bool enableGdt, bool enableIqy)
{
var parentDir = Directory.GetParent(projectPath)?.FullName;
if (string.IsNullOrEmpty(parentDir))
{
Debug.LogWarning($"{TAG} Could not get parent directory");
return;
}
var settingsPath = Path.Combine(parentDir, "settings.gradle");
if (!File.Exists(settingsPath))
{
Debug.LogWarning($"{TAG} Could not find settings.gradle at {settingsPath}");
return;
}
var content = File.ReadAllText(settingsPath);
// Check if already injected
if (content.Contains(DIRICHLET_REPOS_START))
{
Debug.Log($"{TAG} settings.gradle already has Dirichlet repos");
return;
}
// Remove any previously injected content
content = RemoveInjectedContent(content, DIRICHLET_REPOS_START, DIRICHLET_REPOS_END);
var reposBlock = new StringBuilder();
reposBlock.AppendLine(DIRICHLET_REPOS_START);
reposBlock.AppendLine(" google()");
reposBlock.AppendLine(" mavenCentral()");
reposBlock.AppendLine(" flatDir {");
reposBlock.AppendLine(" dirs \"${project(':unityLibrary').projectDir}/libs\", \"${project(':unityLibrary').projectDir}/DirichletMediation/libs\"");
reposBlock.AppendLine(" }");
if (enableCsj)
{
reposBlock.AppendLine(" maven { url 'https://artifact.bytedance.com/repository/pangle' }");
}
if (enableGdt)
{
reposBlock.AppendLine(" maven { url 'https://mirrors.tencent.com/nexus/repository/maven-public/' }");
}
reposBlock.AppendLine($" {DIRICHLET_REPOS_END}");
// Find dependencyResolutionManagement repositories block
var reposPattern = new Regex(@"(dependencyResolutionManagement\s*\{[\s\S]*?repositories\s*\{)");
if (reposPattern.IsMatch(content))
{
content = reposPattern.Replace(content, m =>
m.Groups[1].Value + "\n " + reposBlock.ToString(), 1);
File.WriteAllText(settingsPath, content);
Debug.Log($"{TAG} Updated settings.gradle with Dirichlet Mediation repositories");
}
else
{
Debug.LogWarning($"{TAG} Could not find dependencyResolutionManagement repositories block in settings.gradle");
}
}
private string RemoveInjectedContent(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");
}
}
}
#endif