312 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			C#
		
	
	
	
			
		
		
	
	
			312 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			C#
		
	
	
	
| using System;
 | ||
| using System.Collections.Generic;
 | ||
| using System.Linq;
 | ||
| using System.Reflection;
 | ||
| using GoogleMobileAds.Api;
 | ||
| using UnityEngine;
 | ||
| using Newtonsoft.Json.Linq;
 | ||
| 
 | ||
| namespace WZ
 | ||
| {
 | ||
|     abstract class IStack
 | ||
|     {
 | ||
|         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 abstract string GetFiledName();
 | ||
| 
 | ||
|         public string[] GetStackFromName(string stackName)
 | ||
|         {
 | ||
|             return stackName switch
 | ||
|             {
 | ||
|                 "BannerStack" => GetBannerStack(),
 | ||
|                 "SpStack" => GetSpStack(),
 | ||
|                 "IvStack" => GetIvStack(),
 | ||
|                 "RvStack" => GetRvStack(),
 | ||
|                 "NaStack" => GetNaStack(),
 | ||
|                 _ => Array.Empty<string>()
 | ||
|             };
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     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;
 | ||
|         }
 | ||
| 
 | ||
|         public override string GetFiledName()
 | ||
|         {
 | ||
|             return "zzd";
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     internal class Stack2 : IStack
 | ||
|     {
 | ||
|         private static readonly string[] BannerStack = { "zza", "zzj", "zza", "a", "a", "f", "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", "d", "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;
 | ||
|         }
 | ||
| 
 | ||
|         protected override string[] GetRvStack()
 | ||
|         {
 | ||
|             return RvStack;
 | ||
|         }
 | ||
| 
 | ||
|         protected override string[] GetNaStack()
 | ||
|         {
 | ||
|             return NaStack;
 | ||
|         }
 | ||
| 
 | ||
|         public override string GetFiledName()
 | ||
|         {
 | ||
|             return "d";
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     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>();
 | ||
|         }
 | ||
| 
 | ||
|         public override string GetFiledName()
 | ||
|         {
 | ||
|             return "null";
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
| 
 | ||
|     public class AdmobUtils
 | ||
|     {
 | ||
|         private static IStack _stack;
 | ||
| 
 | ||
|         private static readonly List<IStack> AvailableStrategies = new()
 | ||
|         {
 | ||
|             new Stack1(),
 | ||
|             new Stack2()
 | ||
|             // 新增策略只需在此处添加
 | ||
|         };
 | ||
| 
 | ||
|         public static double GetBannerEcpm(BannerView bannerView)
 | ||
|         {
 | ||
|             return GetEcpm(bannerView, "bannerView", "adView", "BannerStack");
 | ||
|         }
 | ||
| 
 | ||
|         public static double GetRewardedAdEcpm(RewardedAd rewardedAd)
 | ||
|         {
 | ||
|             return GetEcpm(rewardedAd, "androidRewardedAd", "rewardedAd", "RvStack");
 | ||
|         }
 | ||
| 
 | ||
|         public static double GetInterstitialAdEcpm(InterstitialAd interstitialAd)
 | ||
|         {
 | ||
|             return GetEcpm(interstitialAd, "androidInterstitialAd", "interstitialAd", "IvStack");
 | ||
|         }
 | ||
| 
 | ||
|         public static double GetAppOpenAdEcpm(AppOpenAd appOpenAd)
 | ||
|         {
 | ||
|             return GetEcpm(appOpenAd, "androidAppOpenAd", "appOpenAd", "SpStack");
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         public static double GetNativeEcpm(NativeOverlayAd ad)
 | ||
|         {
 | ||
|             return GetEcpm(ad, "nativeOverlayAd", "nativeAd", "NaStack");
 | ||
|         }
 | ||
| 
 | ||
|         private static double GetEcpm(object o, string cShapeFieldName, string javaFieldName, string stack)
 | ||
|         {
 | ||
|             if (_stack is EmptyStack)
 | ||
|             {
 | ||
|                 return 0.0000001;
 | ||
|             }
 | ||
| 
 | ||
|             try
 | ||
|             {
 | ||
|                 if (_stack != null)
 | ||
|                 {
 | ||
|                     return GetEcpm(GetAdValue(GetJavaAdViewOjb(o, cShapeFieldName, javaFieldName), _stack.GetStackFromName(stack)), _stack.GetFiledName());
 | ||
|                 }
 | ||
|             }
 | ||
|             catch (Exception e)
 | ||
|             {
 | ||
|                 LoggerUtils.Error("[AdmobTools] e : " + e.Message + "\t cShapeFieldName : " + cShapeFieldName);
 | ||
|                 return 0.0000001;
 | ||
|             }
 | ||
| 
 | ||
| 
 | ||
|             foreach (var availableStrategy in AvailableStrategies)
 | ||
|             {
 | ||
|                 try
 | ||
|                 {
 | ||
|                     var ecpm = GetEcpm(GetAdValue(GetJavaAdViewOjb(o, cShapeFieldName, javaFieldName), availableStrategy.GetStackFromName(stack)), availableStrategy.GetFiledName());
 | ||
|                     _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);
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
|             _stack = new EmptyStack();
 | ||
| 
 | ||
|             return 0.0000001;
 | ||
|         }
 | ||
| 
 | ||
|         /// <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, string fieldName)
 | ||
|         {
 | ||
|             return obj.Get<long>(fieldName) * 1.0 / 1000000;
 | ||
|         }
 | ||
|     }
 | ||
| } |