282 lines
11 KiB
C#
282 lines
11 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using JetBrains.Annotations;
|
|
using KwaiAds.Scripts.Api;
|
|
using KwaiAds.Scripts.Api.Reward;
|
|
using UnityEngine;
|
|
using static WZ.KwaiAdsConfigParser;
|
|
|
|
namespace WZ
|
|
{
|
|
public class KwaiFloorRvManager : D_MonoSingleton<KwaiFloorRvManager>
|
|
{
|
|
private int _rvParallelRequests = 3;
|
|
private List<FloorConfig> _rvFloorConfigs = new List<FloorConfig>();
|
|
public Dictionary<string, IRewardAdController> _rvFloorAdControllers = new Dictionary<string, IRewardAdController>();
|
|
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 _rvStartLoadTime = 0;
|
|
private int _waterfallRequestCount = 0; // waterfall请求次数
|
|
private Dictionary<string, int> _unitIdRequestCounts = new Dictionary<string, int>(); // 每个unite_id的请求次数
|
|
private string _currentRequestId; // 当前waterfall请求的ID
|
|
|
|
public void InitializeWithFloors()
|
|
{
|
|
// 对楼层按价格从高到低排序
|
|
_sortedFloors = _rvFloorConfigs.OrderByDescending(f => f.price).ToList();
|
|
LoggerUtils.Debug("[kwai] floor reward Sorted floors: " + string.Join(", ", _sortedFloors.Select(f => $"{f.id}:{f.price}")));
|
|
}
|
|
|
|
public void LoadKwaiBiddingConfig()
|
|
{
|
|
_rvParallelRequests = KwaiAdsConfigParser.GetRvParallelRequests();
|
|
_rvFloorConfigs = KwaiAdsConfigParser.GetRvFloorConfigs();
|
|
KwaiAdsManager.Instance._appId = KwaiAdsConfigParser.GetKwaiAppId();
|
|
KwaiAdsManager.Instance._token = KwaiAdsConfigParser.GetKwaiAppToken();
|
|
LoggerUtils.Debug($"[kwai] floor reward bidding config loaded. FloorOpen: {KwaiAdsConfigParser.GetKwaiRvFloorOpen()}, ParallelRequests: {_rvParallelRequests}, Floors: {_rvFloorConfigs.Count}");
|
|
}
|
|
|
|
public void LoadRewardedWithFloors()
|
|
{
|
|
if (_rvFloorConfigs == null || _rvFloorConfigs.Count == 0)
|
|
{
|
|
LoggerUtils.Debug("[kwai] floor reward No floor configs available, using standard load");
|
|
KwaiAdsManager.Instance.LoadRewardedStandard();
|
|
return;
|
|
}
|
|
_rvStartLoadTime = Time.realtimeSinceStartup;
|
|
// 重置状态
|
|
_currentFloorIndex = 0;
|
|
_successfulFloor = null;
|
|
_isRequestingFloors = true;
|
|
_currentRequestId = GenerateRequestId();
|
|
|
|
// 增加waterfall请求计数
|
|
_waterfallRequestCount++;
|
|
// 清理之前的广告控制器
|
|
foreach (var controller in _rvFloorAdControllers.Values)
|
|
{
|
|
controller.Destroy();
|
|
}
|
|
_rvFloorAdControllers.Clear();
|
|
|
|
// 开始请求楼层广告
|
|
RequestNextFloorBatch();
|
|
|
|
AdsActionEvents.TrackKwaiWaterfallRequest(AdsType.Rewarded,
|
|
_currentRequestId,
|
|
_waterfallRequestCount,
|
|
_rvParallelRequests);
|
|
}
|
|
|
|
private void RequestNextFloorBatch()
|
|
{
|
|
if (!_isRequestingFloors || _successfulFloor != null) return;
|
|
|
|
// 获取下一批要请求的楼层
|
|
_currentRequestBatch = new List<FloorConfig>();
|
|
int count = 0;
|
|
|
|
while (_currentFloorIndex < _sortedFloors.Count && count < _rvParallelRequests)
|
|
{
|
|
_currentRequestBatch.Add(_sortedFloors[_currentFloorIndex]);
|
|
_currentFloorIndex++;
|
|
count++;
|
|
}
|
|
|
|
if (_currentRequestBatch.Count == 0)
|
|
{
|
|
// 检查是否还有正在处理的请求
|
|
bool hasPendingRequests = false;
|
|
foreach (var kvp in _rvFloorAdControllers)
|
|
{
|
|
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 reward 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 reward Requesting floor {floor.id} (index: {floorIndex}), unite_id {floor.unite_id} has been requested {GetUniteIdRequestCount(floor.unite_id)} times, request id: {_currentRequestId}");
|
|
|
|
IRewardAdController controller = KwaiAds.Scripts.Api.KwaiAdsSdk.SDK.getRewardAdController();
|
|
_rvFloorAdControllers[floor.id] = controller;
|
|
|
|
KwaiRewardAdRequest kwaiRewardAdRequest = new KwaiRewardAdRequest(floor.unite_id);
|
|
kwaiRewardAdRequest.ExtParams[Constants.Request.BID_FLOOR_PRICE] = floor.price.ToString();
|
|
|
|
controller.Load(kwaiRewardAdRequest,
|
|
new FloorRewardAdListener(this, floor),
|
|
new FloorRewardAdLoadListener(this, floor));
|
|
|
|
AdsActionEvents.TrackKwaiAdunitRequest(AdsType.Rewarded,
|
|
_currentRequestId,
|
|
floor.unite_id,
|
|
floor.price,
|
|
GetWaterfallRequestCount(),
|
|
GetUniteIdRequestCount(floor.unite_id),
|
|
floorIndex);
|
|
}
|
|
|
|
// 处理楼层广告加载成功
|
|
public void OnFloorAdLoaded(FloorConfig floor, IRewardAdController controller, double revenue)
|
|
{
|
|
if (!_isRequestingFloors || _successfulFloor != null) return;
|
|
|
|
// 获取当前楼层在排序列表中的位置
|
|
int floorIndex = GetFloorIndex(floor.id);
|
|
LoggerUtils.Debug($"[kwai] floor reward Floor ad loaded: {floor.id} (index: {floorIndex}) with floor price: {floor.price}, unite_id {floor.unite_id} has been requested {GetUniteIdRequestCount(floor.unite_id)} times, revenue:{revenue}");
|
|
|
|
// 暂停其他并行请求
|
|
_successfulFloor = floor;
|
|
_isRequestingFloors = false;
|
|
|
|
// 取消其他楼层的请求
|
|
foreach (var kvp in _rvFloorAdControllers)
|
|
{
|
|
if (kvp.Key != floor.id)
|
|
{
|
|
kvp.Value.Destroy();
|
|
}
|
|
}
|
|
AdsActionEvents.TrackKwiWaterfallFill(AdsType.Rewarded,
|
|
_currentRequestId,
|
|
floor.unite_id,
|
|
floor.price,
|
|
GetWaterfallRequestCount(),
|
|
GetUniteIdRequestCount(floor.unite_id),
|
|
floorIndex,
|
|
revenue);
|
|
}
|
|
|
|
// 处理楼层广告加载失败
|
|
public void OnFloorAdFailed(FloorConfig floor, string error)
|
|
{
|
|
LoggerUtils.Debug($"[kwai] floor reward 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 IsRewardedAvailable()
|
|
{
|
|
return _successfulFloor != null &&
|
|
_rvFloorAdControllers.ContainsKey(_successfulFloor.id) &&
|
|
_rvFloorAdControllers[_successfulFloor.id] != null &&
|
|
_rvFloorAdControllers[_successfulFloor.id].IsReady();
|
|
}
|
|
|
|
public void ShowRewarded(Action _action)
|
|
{
|
|
if (_successfulFloor != null &&
|
|
_rvFloorAdControllers.ContainsKey(_successfulFloor.id) &&
|
|
_rvFloorAdControllers[_successfulFloor.id] != null)
|
|
{
|
|
_rvFloorAdControllers[_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 : "";
|
|
}
|
|
}
|
|
}
|
|
|