2025-08-30 13:48:51 +00:00
|
|
|
|
using System;
|
2025-09-25 02:20:26 +00:00
|
|
|
|
using System.Collections.Generic;
|
2025-08-30 13:48:51 +00:00
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
using GoogleMobileAds.Api;
|
|
|
|
|
using UnityEngine;
|
2025-08-31 08:26:53 +00:00
|
|
|
|
using Newtonsoft.Json.Linq;
|
2025-08-30 13:48:51 +00:00
|
|
|
|
|
2025-09-01 10:32:50 +00:00
|
|
|
|
namespace WZ
|
2025-08-30 13:48:51 +00:00
|
|
|
|
{
|
2025-09-25 02:20:26 +00:00
|
|
|
|
abstract class IStack
|
2025-08-30 13:48:51 +00:00
|
|
|
|
{
|
2025-09-25 02:20:26 +00:00
|
|
|
|
public abstract string GetStackName();
|
|
|
|
|
protected abstract string[] GetBannerStack();
|
|
|
|
|
protected abstract string[] GetSpStack();
|
|
|
|
|
protected abstract string[] GetIvStack();
|
|
|
|
|
protected abstract string[] GetRvStack();
|
|
|
|
|
protected abstract string[] GetNaStack();
|
|
|
|
|
|
|
|
|
|
public string[] GetStackFromName(string stackName)
|
2025-08-31 08:26:53 +00:00
|
|
|
|
{
|
2025-09-25 02:20:26 +00:00
|
|
|
|
return stackName switch
|
2025-08-31 08:26:53 +00:00
|
|
|
|
{
|
2025-09-25 02:20:26 +00:00
|
|
|
|
"BannerStack" => GetBannerStack(),
|
|
|
|
|
"SpStack" => GetSpStack(),
|
|
|
|
|
"IvStack" => GetIvStack(),
|
|
|
|
|
"RvStack" => GetRvStack(),
|
|
|
|
|
"NaStack" => GetNaStack(),
|
|
|
|
|
_ => Array.Empty<string>()
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-08-31 08:26:53 +00:00
|
|
|
|
|
2025-09-25 02:20:26 +00:00
|
|
|
|
internal class Stack1 : IStack
|
|
|
|
|
{
|
|
|
|
|
private static readonly string[] BannerStack = { "zza", "zzj", "zzi", "zze", "zza", "zzk", "zzae" };
|
|
|
|
|
private static readonly string[] SpStack = { "zzb", "zza", "zzc", "zza", "zzk", "zzae" };
|
|
|
|
|
private static readonly string[] IvStack = { "zzc", "zzj", "zzf", "zzd", "zzae" };
|
|
|
|
|
private static readonly string[] RvStack = { "zzb", "zzi", "zze", "zze", "zzae" };
|
|
|
|
|
private static readonly string[] NaStack = { "zza", "zzb", "zzf", "zzD", "zzb", "zzae" };
|
|
|
|
|
|
|
|
|
|
public override string GetStackName()
|
|
|
|
|
{
|
|
|
|
|
return "Stack1";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override string[] GetBannerStack()
|
|
|
|
|
{
|
|
|
|
|
return BannerStack;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override string[] GetSpStack()
|
|
|
|
|
{
|
|
|
|
|
return SpStack;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override string[] GetIvStack()
|
|
|
|
|
{
|
|
|
|
|
return IvStack;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override string[] GetRvStack()
|
|
|
|
|
{
|
|
|
|
|
return RvStack;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override string[] GetNaStack()
|
|
|
|
|
{
|
|
|
|
|
return NaStack;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal class Stack2 : IStack
|
|
|
|
|
{
|
|
|
|
|
private static readonly string[] BannerStack = { "zza", "zzj", "zza", "a", "a", "e", "a", "e", "ae" };
|
|
|
|
|
private static readonly string[] SpStack = { "zzb", "zza", "a", "a", "a", "e", "ae" };
|
|
|
|
|
private static readonly string[] IvStack = { "zzc", "zza", "a", "a", "d", "d", "ae" };
|
|
|
|
|
private static readonly string[] RvStack = { "zzb", "zza", "b", "g", "e", "ae" };
|
|
|
|
|
private static readonly string[] NaStack = { "zza", "zza", "b", "c", "c", "ae" };
|
|
|
|
|
|
|
|
|
|
public override string GetStackName()
|
|
|
|
|
{
|
|
|
|
|
return "Stack2";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override string[] GetBannerStack()
|
|
|
|
|
{
|
|
|
|
|
return BannerStack;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override string[] GetSpStack()
|
|
|
|
|
{
|
|
|
|
|
return SpStack;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override string[] GetIvStack()
|
|
|
|
|
{
|
|
|
|
|
return IvStack;
|
|
|
|
|
}
|
2025-09-01 15:57:41 +00:00
|
|
|
|
|
2025-09-25 02:20:26 +00:00
|
|
|
|
protected override string[] GetRvStack()
|
|
|
|
|
{
|
|
|
|
|
return RvStack;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override string[] GetNaStack()
|
|
|
|
|
{
|
|
|
|
|
return NaStack;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal class EmptyStack : IStack
|
|
|
|
|
{
|
|
|
|
|
public override string GetStackName()
|
|
|
|
|
{
|
|
|
|
|
return "EmptyStack";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override string[] GetBannerStack()
|
|
|
|
|
{
|
|
|
|
|
return Array.Empty<string>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override string[] GetSpStack()
|
|
|
|
|
{
|
|
|
|
|
return Array.Empty<string>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override string[] GetIvStack()
|
|
|
|
|
{
|
|
|
|
|
return Array.Empty<string>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override string[] GetRvStack()
|
|
|
|
|
{
|
|
|
|
|
return Array.Empty<string>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override string[] GetNaStack()
|
|
|
|
|
{
|
|
|
|
|
return Array.Empty<string>();
|
2025-08-31 08:26:53 +00:00
|
|
|
|
}
|
2025-09-25 02:20:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class AdmobUtils
|
|
|
|
|
{
|
|
|
|
|
private static IStack _stack;
|
|
|
|
|
|
|
|
|
|
private static readonly List<IStack> AvailableStrategies = new()
|
|
|
|
|
{
|
|
|
|
|
new Stack1(),
|
|
|
|
|
new Stack2()
|
|
|
|
|
// 新增策略只需在此处添加
|
|
|
|
|
};
|
2025-09-01 15:57:41 +00:00
|
|
|
|
|
2025-08-30 13:48:51 +00:00
|
|
|
|
public static double GetBannerEcpm(BannerView bannerView)
|
|
|
|
|
{
|
2025-09-25 02:20:26 +00:00
|
|
|
|
return GetEcpm(bannerView, "bannerView", "adView", "BannerStack");
|
2025-08-30 13:48:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static double GetRewardedAdEcpm(RewardedAd rewardedAd)
|
|
|
|
|
{
|
2025-09-25 02:20:26 +00:00
|
|
|
|
return GetEcpm(rewardedAd, "androidRewardedAd", "rewardedAd", "RvStack");
|
2025-08-30 13:48:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static double GetInterstitialAdEcpm(InterstitialAd interstitialAd)
|
|
|
|
|
{
|
2025-09-25 02:20:26 +00:00
|
|
|
|
return GetEcpm(interstitialAd, "androidInterstitialAd", "interstitialAd", "IvStack");
|
2025-08-30 13:48:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static double GetAppOpenAdEcpm(AppOpenAd appOpenAd)
|
|
|
|
|
{
|
2025-09-25 02:20:26 +00:00
|
|
|
|
return GetEcpm(appOpenAd, "androidAppOpenAd", "appOpenAd", "SpStack");
|
2025-08-30 13:48:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
2025-09-01 15:57:41 +00:00
|
|
|
|
|
|
|
|
|
public static double GetNativeEcpm(NativeOverlayAd ad)
|
|
|
|
|
{
|
2025-09-25 02:20:26 +00:00
|
|
|
|
return GetEcpm(ad, "nativeOverlayAd", "nativeAd", "NaStack");
|
2025-09-01 15:57:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
2025-09-25 02:20:26 +00:00
|
|
|
|
private static double GetEcpm(object o, string cShapeFieldName, string javaFieldName, string stack)
|
2025-08-30 13:48:51 +00:00
|
|
|
|
{
|
2025-09-25 02:20:26 +00:00
|
|
|
|
if (_stack is EmptyStack)
|
|
|
|
|
{
|
|
|
|
|
return -0.1;
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-30 13:48:51 +00:00
|
|
|
|
try
|
|
|
|
|
{
|
2025-09-25 02:20:26 +00:00
|
|
|
|
if (_stack != null)
|
|
|
|
|
{
|
|
|
|
|
return GetEcpm(GetAdValue(GetJavaAdViewOjb(o, cShapeFieldName, javaFieldName), _stack.GetStackFromName(stack)));
|
|
|
|
|
}
|
2025-08-30 13:48:51 +00:00
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
|
|
|
|
LoggerUtils.Error("[AdmobTools] e : " + e.Message + "\t cShapeFieldName : " + cShapeFieldName);
|
2025-09-25 02:20:26 +00:00
|
|
|
|
return -0.2;
|
2025-08-30 13:48:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2025-09-25 02:20:26 +00:00
|
|
|
|
foreach (var availableStrategy in AvailableStrategies)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var ecpm = GetEcpm(GetAdValue(GetJavaAdViewOjb(o, cShapeFieldName, javaFieldName), availableStrategy.GetStackFromName(stack)));
|
|
|
|
|
_stack = availableStrategy;
|
|
|
|
|
LoggerUtils.Debug("[AdmobTools] stack name : " + _stack.GetStackName());
|
|
|
|
|
return ecpm;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
|
|
|
|
LoggerUtils.Error("[AdmobTools] stack name " + availableStrategy.GetStackName() + "e : " + e.Message + "\t cShapeFieldName : " + cShapeFieldName);
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-08-30 13:48:51 +00:00
|
|
|
|
|
2025-09-25 02:20:26 +00:00
|
|
|
|
_stack = new EmptyStack();
|
2025-08-30 13:48:51 +00:00
|
|
|
|
|
2025-09-25 02:20:26 +00:00
|
|
|
|
return -1.0;
|
|
|
|
|
}
|
2025-08-30 13:48:51 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取java ad view 对象
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="o">unity admob 实例化对象</param>
|
|
|
|
|
/// <param name="cShapeFieldName">unity 引用 java 桥阶层的属性名</param>
|
|
|
|
|
/// <param name="javaFieldName">java桥阶层,持有ad对象的方法名</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private static AndroidJavaObject GetJavaAdViewOjb(object o, string cShapeFieldName, string javaFieldName)
|
|
|
|
|
{
|
|
|
|
|
if (o == null)
|
|
|
|
|
{
|
|
|
|
|
throw new NullReferenceException("adView is null ; " + cShapeFieldName + "\t " + javaFieldName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var type = o.GetType(); // 获取 BannerView 类型
|
|
|
|
|
|
|
|
|
|
var fieldInfo = type.GetField("_client", BindingFlags.NonPublic | BindingFlags.Instance); // 获取 _client 字段信息
|
|
|
|
|
|
|
|
|
|
if (fieldInfo == null)
|
|
|
|
|
{
|
|
|
|
|
throw new NullReferenceException("fieldInfo is null ; " + cShapeFieldName + "\t " + javaFieldName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var client = fieldInfo.GetValue(o); // 获取 _client 字段的值
|
|
|
|
|
var clientType = client.GetType();
|
|
|
|
|
var bannerViewFieldInfo = clientType.GetField(cShapeFieldName, BindingFlags.NonPublic | BindingFlags.Instance);
|
|
|
|
|
if (bannerViewFieldInfo == null)
|
|
|
|
|
{
|
|
|
|
|
throw new NullReferenceException("cShapeFieldName fieldInfo is null ; " + cShapeFieldName + "\t " + javaFieldName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var bannerViewAndroidJavaObject = (AndroidJavaObject)bannerViewFieldInfo.GetValue(client);
|
|
|
|
|
|
|
|
|
|
var javaAdViewOjb = bannerViewAndroidJavaObject.Get<AndroidJavaObject>(javaFieldName);
|
|
|
|
|
if (javaAdViewOjb == null)
|
|
|
|
|
{
|
|
|
|
|
throw new NullReferenceException("java obj is null ; " + cShapeFieldName + "\t " + javaFieldName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return javaAdViewOjb;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取 admob 的 AdValue 对象
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="obj">admob 广告对象</param>
|
|
|
|
|
/// <param name="stack">内存位置</param>
|
|
|
|
|
/// <returns>AdValue 的对象</returns>
|
|
|
|
|
private static AndroidJavaObject GetAdValue(AndroidJavaObject obj, string[] stack)
|
|
|
|
|
{
|
|
|
|
|
return stack.Aggregate(obj, (current, field) =>
|
|
|
|
|
{
|
|
|
|
|
var androidJavaObject = current.Get<AndroidJavaObject>(field);
|
|
|
|
|
if (androidJavaObject == null)
|
|
|
|
|
{
|
|
|
|
|
throw new NullReferenceException("androidJavaObject is null ; " + current + "\t " + field);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return androidJavaObject;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取 ecpm
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="obj">admob AdValue对象</param>
|
|
|
|
|
/// <returns>广告收益</returns>
|
|
|
|
|
private static double GetEcpm(AndroidJavaObject obj)
|
|
|
|
|
{
|
|
|
|
|
return obj.Get<long>("zzd") * 1.0 / 1000000;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|