SDK_UnityMoney/Assets/Script/SDKManager/AdsSDKManager/KwaiAdsManager/KwaiFloorIvManager.cs

286 lines
11 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using GoogleMobileAds.Common;
using JetBrains.Annotations;
using KwaiAds.Scripts.Api;
using KwaiAds.Scripts.Api.Interstitial;
using KwaiAds.Scripts.Api.Reward;
using UnityEngine;
using static WZ.KwaiAdsConfigParser;
namespace WZ
{
public class KwaiFloorIvManager : D_MonoSingleton<KwaiFloorIvManager>
{
private int _ivParallelRequests = 3;
private List<FloorConfig> _ivFloorConfigs = new List<FloorConfig>();
public Dictionary<string, IInterstitialAdController> _ivFloorAdControllers = new Dictionary<string, IInterstitialAdController>();
private List<FloorConfig> _sortedFloors = new List<FloorConfig>();
private int _currentFloorIndex = 0;
private bool _isRequestingFloors = false;
private List<FloorConfig> _currentRequestBatch = new List<FloorConfig>();
private FloorConfig _successfulFloor = null;
public float _ivStartLoadTime = 0;
private int _waterfallRequestCount = 0; // waterfall请求次数
private Dictionary<string, int> _unitIdRequestCounts = new Dictionary<string, int>(); // 每个unit_id的请求次数
private string _currentRequestId; // 当前waterfall请求的ID
public void InitializeWithFloors()
{
// 对楼层按价格从高到低排序
_sortedFloors = _ivFloorConfigs.OrderByDescending(f => f.price).ToList();
LoggerUtils.Debug("[kwai] floor inter Sorted floors: " + string.Join(", ", _sortedFloors.Select(f => $"{f.id}:{f.price}")));
}
public void LoadKwaiBiddingConfig()
{
_ivParallelRequests = KwaiAdsConfigParser.GetIvParallelRequests();
_ivFloorConfigs = KwaiAdsConfigParser.GetIvFloorConfigs();
LoggerUtils.Debug($"[kwai] floor inter bidding config loaded. FloorOpen: {KwaiAdsConfigParser.GetKwaiIvFloorOpen()}, ParallelRequests: {_ivParallelRequests}, Floors: {_ivFloorConfigs.Count}");
}
public void LoadInterstitialWithFloors()
{
if (_ivFloorConfigs == null || _ivFloorConfigs.Count == 0)
{
LoggerUtils.Debug("[kwai] floor inter No floor configs available, using standard load");
KwaiAdsManager.Instance.LoadRewardedStandard();
return;
}
_ivStartLoadTime = Time.realtimeSinceStartup;
// 重置状态
_currentFloorIndex = 0;
_successfulFloor = null;
_isRequestingFloors = true;
_currentRequestId = GenerateRequestId();
// 增加waterfall请求计数
_waterfallRequestCount++;
// 清理之前的广告控制器
foreach (var controller in _ivFloorAdControllers.Values)
{
controller.Destroy();
}
_ivFloorAdControllers.Clear();
// 开始请求楼层广告
RequestNextFloorBatch();
AdsActionEvents.TrackKwaiWaterfallRequest(AdsType.Interstitial,
_currentRequestId,
_waterfallRequestCount,
_ivParallelRequests);
}
private void RequestNextFloorBatch()
{
if (!_isRequestingFloors || _successfulFloor != null) return;
// 获取下一批要请求的楼层
_currentRequestBatch = new List<FloorConfig>();
int count = 0;
while (_currentFloorIndex < _sortedFloors.Count && count < _ivParallelRequests)
{
_currentRequestBatch.Add(_sortedFloors[_currentFloorIndex]);
_currentFloorIndex++;
count++;
}
if (_currentRequestBatch.Count == 0)
{
// 检查是否还有正在处理的请求
bool hasPendingRequests = false;
foreach (var kvp in _ivFloorAdControllers)
{
if (kvp.Value != null && !kvp.Value.IsReady())
{
hasPendingRequests = true;
break;
}
}
if (!hasPendingRequests)
{
// 所有楼层都请求完毕,并且没有正在处理的请求,确实没有填充
LoggerUtils.Debug("[kwai] floor reward All floors requested, no fill");
_isRequestingFloors = false;
}
}
LoggerUtils.Debug($"[kwai] floor inter Requesting floor batch: {string.Join(", ", _currentRequestBatch.Select(f => $"{f.id}({f.price})"))}");
// 并行请求当前批次的楼层
foreach (var floor in _currentRequestBatch)
{
RequestFloorAd(floor);
}
}
private void RequestFloorAd(FloorConfig floor)
{
// 更新unite_id请求计数
if (!_unitIdRequestCounts.ContainsKey(floor.unite_id))
{
_unitIdRequestCounts[floor.unite_id] = 0;
}
_unitIdRequestCounts[floor.unite_id]++;
// 获取当前楼层在排序列表中的位置
int floorIndex = GetFloorIndex(floor.id);
LoggerUtils.Debug($"[kwai] floor inter Requesting floor {floor.id} (index: {floorIndex}), unite_id {floor.unite_id} has been requested {_unitIdRequestCounts[floor.unite_id]} times, request id: {GetUniteIdRequestCount(floor.unite_id)}");
IInterstitialAdController controller = KwaiAds.Scripts.Api.KwaiAdsSdk.SDK.getInterstitialAdController(); ;
_ivFloorAdControllers[floor.id] = controller;
KwaiInterstitialAdRequest kwaiInterstitialAdRequest = new KwaiInterstitialAdRequest(floor.unite_id);
kwaiInterstitialAdRequest.ExtParams[Constants.Request.BID_FLOOR_PRICE] = floor.price.ToString();
controller.Load(kwaiInterstitialAdRequest,
new FloorInterAdListener(this, floor),
new FloorInterAdLoadListener(this, floor));
AdsActionEvents.TrackKwaiAdunitRequest(AdsType.Interstitial,
_currentRequestId,
floor.unite_id,
floor.price,
GetWaterfallRequestCount(),
GetUniteIdRequestCount(floor.unite_id),
floorIndex);
}
// 处理楼层广告加载成功
public void OnFloorAdLoaded(FloorConfig floor, IInterstitialAdController controller, double revenue)
{
if (!_isRequestingFloors || _successfulFloor != null) return;
// 获取当前楼层在排序列表中的位置
int floorIndex = GetFloorIndex(floor.id);
LoggerUtils.Debug($"[kwai] floor inter ad loaded: {floor.id} (index: {floorIndex}) with price: {floor.price}, unite_id {floor.unite_id} has been requested {GetUniteIdRequestCount(floor.unite_id)} times, revenue: {revenue}, request id: {_currentRequestId}");
// 暂停其他并行请求
_successfulFloor = floor;
_isRequestingFloors = false;
// 取消其他楼层的请求
foreach (var kvp in _ivFloorAdControllers)
{
if (kvp.Key != floor.id)
{
kvp.Value.Destroy();
}
}
AdsActionEvents.TrackKwiWaterfallFill(AdsType.Interstitial,
_currentRequestId,
floor.unite_id,
floor.price,
GetWaterfallRequestCount(),
GetUniteIdRequestCount(floor.unite_id),
floorIndex,
revenue);
}
// 处理楼层广告加载失败
public void OnFloorAdFailed(FloorConfig floor, string error)
{
LoggerUtils.Debug($"[kwai] floor inter ad failed: {floor.id} with error: {error} _isRequestingFloors:{!_isRequestingFloors} _successfulFloor: {_successfulFloor != null}");
if (!_isRequestingFloors || _successfulFloor != null) return;
// 移除失败floor
if (_currentRequestBatch.Contains(floor)) _currentRequestBatch.Remove(floor);
// 检查当前批次是否全部失败
bool allFailedInBatch = true;
if (_currentRequestBatch.Count > 0) allFailedInBatch = false;
// 如果当前批次全部失败,请求下一批
if (allFailedInBatch)
{
RequestNextFloorBatch();
}
}
public bool IsInterstitialAdAvailable()
{
return _successfulFloor != null &&
_ivFloorAdControllers.ContainsKey(_successfulFloor.id) &&
_ivFloorAdControllers[_successfulFloor.id] != null &&
_ivFloorAdControllers[_successfulFloor.id].IsReady();
}
public void ShowInterstitialAd(Action _action)
{
if (_successfulFloor != null &&
_ivFloorAdControllers.ContainsKey(_successfulFloor.id) &&
_ivFloorAdControllers[_successfulFloor.id] != null)
{
_ivFloorAdControllers[_successfulFloor.id].Show();
}
else
{
_action?.Invoke();
}
}
/// <summary>
/// 获取当前waterfall请求次数
/// </summary>
public int GetWaterfallRequestCount()
{
return _waterfallRequestCount;
}
/// <summary>
/// 获取当前waterfall请求次数
/// </summary>
public int GetUniteIdRequestCount(string unitId)
{
return _unitIdRequestCounts.TryGetValue(unitId, out var time) ? time : 0;
}
/// <summary>
/// 根据floor.id获取其在排序后的楼层列表中的索引位置
/// </summary>
public int GetFloorIndex(string floorId)
{
for (int i = 0; i < _sortedFloors.Count; i++)
{
if (_sortedFloors[i].id == floorId)
{
return i;
}
}
return -1; // 未找到
}
/// <summary>
/// 获取当前Request ID
/// </summary>
public string GetCurrentRequestId()
{
return _currentRequestId;
}
/// <summary>
/// 生成唯一的Request ID
/// </summary>
private string GenerateRequestId()
{
return Guid.NewGuid().ToString("N");
}
public string GetSuccessfulFloorUnitId()
{
return _successfulFloor != null ? _successfulFloor.unite_id : "";
}
}
}