2026-06-04 17:16:17 +08:00
|
|
|
#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);
|
|
|
|
|
|
2026-06-12 17:55:17 +08:00
|
|
|
// Local AAR files are imported by Unity's PluginImporter from Assets/Plugins/Android.
|
|
|
|
|
// Do not declare them here again, otherwise exported Gradle projects can get duplicate classes.
|
2026-06-04 17:16:17 +08:00
|
|
|
if (enableIqy)
|
|
|
|
|
{
|
|
|
|
|
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
|