| 
									
										
										
										
											2025-09-15 02:19:03 +00:00
										 |  |  | using System; | 
					
						
							|  |  |  | using System.Collections; | 
					
						
							|  |  |  | using System.Collections.Generic; | 
					
						
							|  |  |  | using System.Linq; | 
					
						
							|  |  |  | using JetBrains.Annotations; | 
					
						
							| 
									
										
										
										
											2025-09-15 10:41:43 +00:00
										 |  |  | using KwaiAds.Scripts.Api; | 
					
						
							| 
									
										
										
										
											2025-09-15 02:19:03 +00:00
										 |  |  | using KwaiAds.Scripts.Api.Reward; | 
					
						
							|  |  |  | using UnityEngine; | 
					
						
							|  |  |  | using static WZ.KwaiAdsConfigParser; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace WZ | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2025-09-15 05:58:43 +00:00
										 |  |  |     public class KwaiFloorRvManager : D_MonoSingleton<KwaiFloorRvManager> | 
					
						
							| 
									
										
										
										
											2025-09-15 02:19:03 +00:00
										 |  |  |     { | 
					
						
							|  |  |  |         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; | 
					
						
							| 
									
										
										
										
											2025-09-15 05:58:43 +00:00
										 |  |  |         public float _rvStartLoadTime = 0; | 
					
						
							| 
									
										
										
										
											2025-09-15 10:41:43 +00:00
										 |  |  |         private int _waterfallRequestCount = 0; // waterfall请求次数 | 
					
						
							| 
									
										
										
										
											2025-09-15 11:06:55 +00:00
										 |  |  |         private Dictionary<string, int> _unitIdRequestCounts = new Dictionary<string, int>(); // 每个unite_id的请求次数 | 
					
						
							| 
									
										
										
										
											2025-09-15 10:41:43 +00:00
										 |  |  |         private string _currentRequestId; // 当前waterfall请求的ID | 
					
						
							| 
									
										
										
										
											2025-09-15 05:58:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-15 02:19:03 +00:00
										 |  |  |         public void InitializeWithFloors() | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             // 对楼层按价格从高到低排序 | 
					
						
							|  |  |  |             _sortedFloors = _rvFloorConfigs.OrderByDescending(f => f.price).ToList(); | 
					
						
							| 
									
										
										
										
											2025-09-15 05:58:43 +00:00
										 |  |  |             LoggerUtils.Debug("[kwai] floor reward Sorted floors: " + string.Join(", ", _sortedFloors.Select(f => $"{f.id}:{f.price}"))); | 
					
						
							| 
									
										
										
										
											2025-09-15 02:19:03 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public void LoadKwaiBiddingConfig() | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             _rvParallelRequests = KwaiAdsConfigParser.GetRvParallelRequests(); | 
					
						
							|  |  |  |             _rvFloorConfigs = KwaiAdsConfigParser.GetRvFloorConfigs(); | 
					
						
							|  |  |  |             KwaiAdsManager.Instance._appId = KwaiAdsConfigParser.GetKwaiAppId(); | 
					
						
							|  |  |  |             KwaiAdsManager.Instance._token = KwaiAdsConfigParser.GetKwaiAppToken(); | 
					
						
							| 
									
										
										
										
											2025-09-15 05:58:43 +00:00
										 |  |  |             LoggerUtils.Debug($"[kwai] floor reward bidding config loaded. FloorOpen: {KwaiAdsConfigParser.GetKwaiRvFloorOpen()}, ParallelRequests: {_rvParallelRequests}, Floors: {_rvFloorConfigs.Count}"); | 
					
						
							| 
									
										
										
										
											2025-09-15 02:19:03 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public void LoadRewardedWithFloors() | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (_rvFloorConfigs == null || _rvFloorConfigs.Count == 0) | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-09-15 05:58:43 +00:00
										 |  |  |                 LoggerUtils.Debug("[kwai] floor reward No floor configs available, using standard load"); | 
					
						
							| 
									
										
										
										
											2025-09-15 02:19:03 +00:00
										 |  |  |                 KwaiAdsManager.Instance.LoadRewardedStandard(); | 
					
						
							|  |  |  |                 return; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-09-15 05:58:43 +00:00
										 |  |  |             _rvStartLoadTime = Time.realtimeSinceStartup; | 
					
						
							| 
									
										
										
										
											2025-09-15 02:19:03 +00:00
										 |  |  |             // 重置状态 | 
					
						
							|  |  |  |             _currentFloorIndex = 0; | 
					
						
							|  |  |  |             _successfulFloor = null; | 
					
						
							|  |  |  |             _isRequestingFloors = true; | 
					
						
							| 
									
										
										
										
											2025-09-15 11:06:55 +00:00
										 |  |  |             _currentRequestId = GenerateRequestId(); | 
					
						
							| 
									
										
										
										
											2025-09-15 10:41:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             // 增加waterfall请求计数 | 
					
						
							|  |  |  |             _waterfallRequestCount++; | 
					
						
							| 
									
										
										
										
											2025-09-15 02:19:03 +00:00
										 |  |  |             // 清理之前的广告控制器 | 
					
						
							|  |  |  |             foreach (var controller in _rvFloorAdControllers.Values) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 controller.Destroy(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             _rvFloorAdControllers.Clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // 开始请求楼层广告 | 
					
						
							|  |  |  |             RequestNextFloorBatch(); | 
					
						
							| 
									
										
										
										
											2025-09-15 11:06:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-16 08:19:07 +00:00
										 |  |  |             AdsActionEvents.TrackKwaiWaterfallRequest(AdsType.Rewarded, | 
					
						
							|  |  |  |                 _currentRequestId, | 
					
						
							|  |  |  |                 _waterfallRequestCount, | 
					
						
							|  |  |  |                 _rvParallelRequests); | 
					
						
							| 
									
										
										
										
											2025-09-15 02:19:03 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         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) | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-09-16 08:19:07 +00:00
										 |  |  |                 // 检查是否还有正在处理的请求 | 
					
						
							|  |  |  |                 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; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2025-09-15 02:19:03 +00:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-15 05:58:43 +00:00
										 |  |  |             LoggerUtils.Debug($"[kwai] floor reward Requesting floor batch: {string.Join(", ", _currentRequestBatch.Select(f => $"{f.id}({f.price})"))}"); | 
					
						
							| 
									
										
										
										
											2025-09-15 02:19:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             // 并行请求当前批次的楼层 | 
					
						
							|  |  |  |             foreach (var floor in _currentRequestBatch) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 RequestFloorAd(floor); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private void RequestFloorAd(FloorConfig floor) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-09-15 10:41:43 +00:00
										 |  |  |             // 更新unite_id请求计数 | 
					
						
							| 
									
										
										
										
											2025-09-15 11:06:55 +00:00
										 |  |  |             if (!_unitIdRequestCounts.ContainsKey(floor.unite_id)) | 
					
						
							| 
									
										
										
										
											2025-09-15 10:41:43 +00:00
										 |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-09-15 11:06:55 +00:00
										 |  |  |                 _unitIdRequestCounts[floor.unite_id] = 0; | 
					
						
							| 
									
										
										
										
											2025-09-15 10:41:43 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-09-15 11:06:55 +00:00
										 |  |  |             _unitIdRequestCounts[floor.unite_id]++; | 
					
						
							| 
									
										
										
										
											2025-09-15 10:41:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             // 获取当前楼层在排序列表中的位置 | 
					
						
							|  |  |  |             int floorIndex = GetFloorIndex(floor.id); | 
					
						
							| 
									
										
										
										
											2025-09-15 11:06:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             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}"); | 
					
						
							| 
									
										
										
										
											2025-09-15 10:41:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-15 02:19:03 +00:00
										 |  |  |             IRewardAdController controller = KwaiAds.Scripts.Api.KwaiAdsSdk.SDK.getRewardAdController(); | 
					
						
							|  |  |  |             _rvFloorAdControllers[floor.id] = controller; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             KwaiRewardAdRequest kwaiRewardAdRequest = new KwaiRewardAdRequest(floor.unite_id); | 
					
						
							| 
									
										
										
										
											2025-09-15 10:41:43 +00:00
										 |  |  |             kwaiRewardAdRequest.ExtParams[Constants.Request.BID_FLOOR_PRICE] = floor.price.ToString(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-15 02:19:03 +00:00
										 |  |  |             controller.Load(kwaiRewardAdRequest, | 
					
						
							|  |  |  |                 new FloorRewardAdListener(this, floor), | 
					
						
							|  |  |  |                 new FloorRewardAdLoadListener(this, floor)); | 
					
						
							| 
									
										
										
										
											2025-09-15 11:06:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             AdsActionEvents.TrackKwaiAdunitRequest(AdsType.Rewarded, | 
					
						
							|  |  |  |                 _currentRequestId, | 
					
						
							|  |  |  |                 floor.unite_id, | 
					
						
							|  |  |  |                 floor.price, | 
					
						
							|  |  |  |                 GetWaterfallRequestCount(), | 
					
						
							|  |  |  |                 GetUniteIdRequestCount(floor.unite_id), | 
					
						
							|  |  |  |                 floorIndex); | 
					
						
							| 
									
										
										
										
											2025-09-15 02:19:03 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 处理楼层广告加载成功 | 
					
						
							| 
									
										
										
										
											2025-09-15 11:06:55 +00:00
										 |  |  |         public void OnFloorAdLoaded(FloorConfig floor, IRewardAdController controller,double revenue) | 
					
						
							| 
									
										
										
										
											2025-09-15 02:19:03 +00:00
										 |  |  |         { | 
					
						
							|  |  |  |             if (!_isRequestingFloors || _successfulFloor != null) return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-15 10:41:43 +00:00
										 |  |  |             // 获取当前楼层在排序列表中的位置 | 
					
						
							|  |  |  |             int floorIndex = GetFloorIndex(floor.id); | 
					
						
							| 
									
										
										
										
											2025-09-15 11:06:55 +00:00
										 |  |  |             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}"); | 
					
						
							| 
									
										
										
										
											2025-09-15 02:19:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             // 暂停其他并行请求 | 
					
						
							|  |  |  |             _successfulFloor = floor; | 
					
						
							|  |  |  |             _isRequestingFloors = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // 取消其他楼层的请求 | 
					
						
							|  |  |  |             foreach (var kvp in _rvFloorAdControllers) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 if (kvp.Key != floor.id) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     kvp.Value.Destroy(); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-09-15 11:06:55 +00:00
										 |  |  |             AdsActionEvents.TrackKwiWaterfallFill(AdsType.Rewarded, | 
					
						
							|  |  |  |                 _currentRequestId, | 
					
						
							|  |  |  |                 floor.unite_id, | 
					
						
							|  |  |  |                 floor.price, | 
					
						
							|  |  |  |                 GetWaterfallRequestCount(), | 
					
						
							|  |  |  |                 GetUniteIdRequestCount(floor.unite_id), | 
					
						
							|  |  |  |                 floorIndex, | 
					
						
							|  |  |  |                 revenue); | 
					
						
							| 
									
										
										
										
											2025-09-15 02:19:03 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 处理楼层广告加载失败 | 
					
						
							|  |  |  |         public void OnFloorAdFailed(FloorConfig floor, string error) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-09-16 08:19:07 +00:00
										 |  |  |             LoggerUtils.Debug($"[kwai] floor reward ad failed: {floor.id} with error: {error} _isRequestingFloors:{!_isRequestingFloors} _successfulFloor: {_successfulFloor != null}" ); | 
					
						
							| 
									
										
										
										
											2025-09-15 02:19:03 +00:00
										 |  |  |             if (!_isRequestingFloors || _successfulFloor != null) return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-16 08:19:07 +00:00
										 |  |  |             // 移除失败floor | 
					
						
							|  |  |  |             if(_currentRequestBatch.Contains(floor))_currentRequestBatch.Remove(floor); | 
					
						
							|  |  |  |              | 
					
						
							| 
									
										
										
										
											2025-09-15 02:19:03 +00:00
										 |  |  |             // 检查当前批次是否全部失败 | 
					
						
							|  |  |  |             bool allFailedInBatch = true; | 
					
						
							| 
									
										
										
										
											2025-09-16 08:19:07 +00:00
										 |  |  |             if (_currentRequestBatch.Count > 0) allFailedInBatch = false;             | 
					
						
							| 
									
										
										
										
											2025-09-15 02:19:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             // 如果当前批次全部失败,请求下一批 | 
					
						
							|  |  |  |             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) | 
					
						
							| 
									
										
										
										
											2025-09-15 10:41:43 +00:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-09-15 02:19:03 +00:00
										 |  |  |             if (_successfulFloor != null && | 
					
						
							|  |  |  |                     _rvFloorAdControllers.ContainsKey(_successfulFloor.id) && | 
					
						
							|  |  |  |                     _rvFloorAdControllers[_successfulFloor.id] != null) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 _rvFloorAdControllers[_successfulFloor.id].Show(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 _action?.Invoke(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-09-15 10:41:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         /// <summary> | 
					
						
							|  |  |  |         /// 获取当前waterfall请求次数 | 
					
						
							|  |  |  |         /// </summary> | 
					
						
							|  |  |  |         public int GetWaterfallRequestCount() | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             return _waterfallRequestCount; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /// <summary> | 
					
						
							|  |  |  |         /// 获取当前waterfall请求次数 | 
					
						
							|  |  |  |         /// </summary> | 
					
						
							|  |  |  |         public int GetUniteIdRequestCount(string unitId) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-09-15 11:06:55 +00:00
										 |  |  |             return _unitIdRequestCounts.TryGetValue(unitId, out var time) ? time : 0; | 
					
						
							| 
									
										
										
										
											2025-09-15 10:41:43 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /// <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"); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-09-15 02:19:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 |