fix:1、修复bug 2、删除不用的代码和资源,sdk等
This commit is contained in:
+280
-280
@@ -1,281 +1,281 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using DataEyeAnalytics;
|
||||
using Newtonsoft.Json;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BallKingdomCrush
|
||||
{
|
||||
public class BIManager : MonoBehaviour
|
||||
{
|
||||
private static BIManager _instance;
|
||||
private static readonly object _initLock = new object();
|
||||
|
||||
// 状态标志
|
||||
private bool _initialized = false; // 仅在初始化成功后为 true
|
||||
private bool _initializing = false; // 防止并发多次尝试初始化
|
||||
|
||||
|
||||
private string ntpServer = "time.windows.com";
|
||||
private string defaultChannel = "gp";
|
||||
private int maxInitRetries = 6;
|
||||
private float retryIntervalSeconds = 0.5f;
|
||||
|
||||
public static BIManager Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
var go = new GameObject("BIManager");
|
||||
DontDestroyOnLoad(go);
|
||||
_instance = go.AddComponent<BIManager>();
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
// 单例保护:如果场景里已有实例,销毁重复的
|
||||
if (_instance == null)
|
||||
{
|
||||
_instance = this;
|
||||
DontDestroyOnLoad(gameObject);
|
||||
}
|
||||
else if (_instance != this)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
// Start 调用 InitBI 是安全的:InitBI 本身是幂等且线程安全的
|
||||
InitBI();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 对外统一初始化入口(幂等、线程安全)
|
||||
/// </summary>
|
||||
public void InitBI()
|
||||
{
|
||||
// 快速检查
|
||||
if (_initialized) return;
|
||||
|
||||
lock (_initLock)
|
||||
{
|
||||
if (_initialized || _initializing)
|
||||
{
|
||||
// 已经初始化或正在初始化,直接返回
|
||||
return;
|
||||
}
|
||||
|
||||
_initializing = true;
|
||||
}
|
||||
|
||||
// 使用协程执行初始化(必要时可以做重试)
|
||||
StartCoroutine(DoInitCoroutine());
|
||||
}
|
||||
|
||||
private IEnumerator DoInitCoroutine()
|
||||
{
|
||||
try
|
||||
{
|
||||
int attempt = 0;
|
||||
Exception lastException = null;
|
||||
|
||||
while (attempt < maxInitRetries)
|
||||
{
|
||||
attempt++;
|
||||
try
|
||||
{
|
||||
// 这里不主动调用 DataEyeAnalyticsAPI.Init(...) 假设你使用的是场景里的 DataEyeAnalytics 预制体,
|
||||
// SDK 会在预制体 Awake/Start 里初始化。如果你的流程是手动 Init,请在这里调用 Init(appId)。
|
||||
|
||||
// 1) 校准时间(默认实例)
|
||||
DataEyeAnalyticsAPI.CalibrateTimeWithNtp(ntpServer);
|
||||
|
||||
// 2) 设置超参数
|
||||
var superProperties = new Dictionary<string, object>
|
||||
{
|
||||
{ "channel", defaultChannel }
|
||||
};
|
||||
DataEyeAnalyticsAPI.SetSuperProperties(superProperties);
|
||||
|
||||
// 3) 开启自动采集
|
||||
DataEyeAnalyticsAPI.EnableAutoTrack(AUTO_TRACK_EVENTS.ALL);
|
||||
|
||||
// 如果上面没有抛异常,认为初始化成功
|
||||
_initialized = true;
|
||||
Debug.Log($"[BIManager] InitBI succeeded on attempt {attempt}");
|
||||
yield break;
|
||||
}
|
||||
catch (ArgumentNullException ane)
|
||||
{
|
||||
// 典型:DataEye 内部 instance 还没创建(appId 为 null) -> retry
|
||||
lastException = ane;
|
||||
Debug.LogWarning(
|
||||
$"[BIManager] DataEye not ready (attempt {attempt}), will retry. msg={ane.Message}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 其他异常,记录并决定是否重试
|
||||
lastException = ex;
|
||||
Debug.LogWarning($"[BIManager] InitBI attempt {attempt} threw: {ex.Message}");
|
||||
}
|
||||
|
||||
// 等待后重试
|
||||
yield return new WaitForSeconds(retryIntervalSeconds);
|
||||
}
|
||||
|
||||
// 重试用尽仍失败 —— 打日志(不再抛异常以免影响游戏流程)
|
||||
Debug.LogError("[BIManager] InitBI failed after retries. Last exception: " +
|
||||
(lastException?.ToString() ?? "null"));
|
||||
}
|
||||
finally
|
||||
{
|
||||
lock (_initLock)
|
||||
{
|
||||
_initializing = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ================= 通用埋点 =================
|
||||
public void TrackEvent(string eventName, Dictionary<string, object> properties = null)
|
||||
{
|
||||
if (properties == null)
|
||||
properties = new Dictionary<string, object>();
|
||||
|
||||
DataEyeAnalyticsAPI.Track(eventName, properties);
|
||||
DataEyeAnalyticsAPI.Flush();
|
||||
|
||||
Debug.Log($"[BI] 事件上报: {eventName}, 属性={JsonConvert.SerializeObject(properties)}");
|
||||
}
|
||||
|
||||
// ================= 预制事件封装 =================
|
||||
|
||||
/// <summary>
|
||||
/// 上报广告事件
|
||||
/// </summary>
|
||||
/// <param name="eventName"></param>
|
||||
/// <param name="adType">Native,RewardedVideo,Banner,Interstitial,Splash</param>
|
||||
/// <param name="placementId">聚合广告位id</param>
|
||||
/// <param name="networkFirmId">广告网络ID</param>
|
||||
public void TrackAdEvent(string eventName, string adType, string placementId = null,
|
||||
string networkFirmId = null, double revenue = 0, string scene = null, string currency = "USD")
|
||||
{
|
||||
var props = new Dictionary<string, object>
|
||||
{
|
||||
{ "ad_type", adType }
|
||||
};
|
||||
|
||||
if (!string.IsNullOrEmpty(placementId))
|
||||
props["PlacementId"] = placementId;
|
||||
|
||||
if (!string.IsNullOrEmpty(networkFirmId))
|
||||
props["NetworkFirmId"] = networkFirmId;
|
||||
|
||||
if (revenue > 0)
|
||||
{
|
||||
props["Revenue"] = revenue;
|
||||
props["Ecpm"] = revenue * 1000;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(scene))
|
||||
props["scene"] = scene;
|
||||
|
||||
if (!string.IsNullOrEmpty(currency))
|
||||
props["Currency"] = currency;
|
||||
|
||||
|
||||
TrackEvent(eventName, props);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 上报内购事件
|
||||
/// </summary>
|
||||
/// <param name="revenue">收入</param>
|
||||
/// <param name="currency">币种</param>
|
||||
/// <param name="payType">支付方式 0=商店支付,1=三方支付</param>
|
||||
/// <param name="itemId">sku</param>
|
||||
/// <param name="status">order:下单 paid:付费成功 paid_err:扣款失败</param>
|
||||
/// <param name="itemName">商品名称</param>
|
||||
/// <param name="msg">如果遇到异常或相关情况,将err_msg进行上报</param>
|
||||
public void TrackPurchase(double revenue, string currency, string payType, string itemId,
|
||||
string status, string itemName = null, string msg = null)
|
||||
{
|
||||
var props = new Dictionary<string, object>
|
||||
{
|
||||
{ "Revenue", revenue },
|
||||
{ "Currency", currency },
|
||||
{ "type", payType },
|
||||
{ "item_id", itemId },
|
||||
{ "purchase_status", status }
|
||||
};
|
||||
|
||||
if (!string.IsNullOrEmpty(itemName))
|
||||
props["item_name"] = itemName;
|
||||
if (!string.IsNullOrEmpty(msg))
|
||||
props["msg"] = msg;
|
||||
|
||||
TrackEvent(BIEvent.PURCHASE, props);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 上报页面浏览
|
||||
/// </summary>
|
||||
public void TrackPageView(string pageName)
|
||||
{
|
||||
var props = new Dictionary<string, object>
|
||||
{
|
||||
{ "page_name", pageName } // 例如 "loading"、"game"
|
||||
};
|
||||
|
||||
TrackEvent(BIEvent.PAGE_VIEW, props);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AB 分组埋点
|
||||
/// </summary>
|
||||
public void TrackABConfig(int responseTime)
|
||||
{
|
||||
var props = new Dictionary<string, object>
|
||||
{
|
||||
{ "response_time", responseTime }
|
||||
};
|
||||
|
||||
TrackEvent(BIEvent.AB_CONFIG, props);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class BIEvent
|
||||
{
|
||||
// 自动采集(SDK 开启自动采集即可,不需要手动埋点)
|
||||
public const string APP_INSTALL = "app_install";
|
||||
public const string APP_START = "app_start";
|
||||
public const string APP_END = "app_end";
|
||||
public const string APP_VIEW = "app_view";
|
||||
public const string APP_CRASH = "app_crash";
|
||||
|
||||
// 内部预制事件
|
||||
public const string AD_REQUEST = "ad_request"; // 广告请求
|
||||
public const string AD_INVENTORY = "ad_inventory"; // 广告填充的时候
|
||||
public const string AD_IMP = "ad_imp"; // 广告展示
|
||||
public const string AD_CLICK = "ad_click"; // 广告点击
|
||||
|
||||
public const string PURCHASE = "purchase"; // 内购
|
||||
|
||||
// 页面相关
|
||||
public const string PAGE_VIEW = "page_view_customize";
|
||||
|
||||
// 其他业务事件(AB 测试等)
|
||||
public const string AB_CONFIG = "config"; // AB
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using DataEyeAnalytics;
|
||||
using Newtonsoft.Json;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BallKingdomCrush
|
||||
{
|
||||
public class BIManager : MonoBehaviour
|
||||
{
|
||||
private static BIManager _instance;
|
||||
private static readonly object _initLock = new object();
|
||||
|
||||
// 状态标志
|
||||
private bool _initialized = false; // 仅在初始化成功后为 true
|
||||
private bool _initializing = false; // 防止并发多次尝试初始化
|
||||
|
||||
|
||||
private string ntpServer = "time.windows.com";
|
||||
private string defaultChannel = "gp";
|
||||
private int maxInitRetries = 6;
|
||||
private float retryIntervalSeconds = 0.5f;
|
||||
|
||||
public static BIManager Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
var go = new GameObject("BIManager");
|
||||
DontDestroyOnLoad(go);
|
||||
_instance = go.AddComponent<BIManager>();
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
// 单例保护:如果场景里已有实例,销毁重复的
|
||||
if (_instance == null)
|
||||
{
|
||||
_instance = this;
|
||||
DontDestroyOnLoad(gameObject);
|
||||
}
|
||||
else if (_instance != this)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
// Start 调用 InitBI 是安全的:InitBI 本身是幂等且线程安全的
|
||||
InitBI();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 对外统一初始化入口(幂等、线程安全)
|
||||
/// </summary>
|
||||
public void InitBI()
|
||||
{
|
||||
// 快速检查
|
||||
if (_initialized) return;
|
||||
|
||||
lock (_initLock)
|
||||
{
|
||||
if (_initialized || _initializing)
|
||||
{
|
||||
// 已经初始化或正在初始化,直接返回
|
||||
return;
|
||||
}
|
||||
|
||||
_initializing = true;
|
||||
}
|
||||
|
||||
// 使用协程执行初始化(必要时可以做重试)
|
||||
StartCoroutine(DoInitCoroutine());
|
||||
}
|
||||
|
||||
private IEnumerator DoInitCoroutine()
|
||||
{
|
||||
try
|
||||
{
|
||||
int attempt = 0;
|
||||
Exception lastException = null;
|
||||
|
||||
while (attempt < maxInitRetries)
|
||||
{
|
||||
attempt++;
|
||||
try
|
||||
{
|
||||
// 这里不主动调用 DataEyeAnalyticsAPI.Init(...) 假设你使用的是场景里的 DataEyeAnalytics 预制体,
|
||||
// SDK 会在预制体 Awake/Start 里初始化。如果你的流程是手动 Init,请在这里调用 Init(appId)。
|
||||
|
||||
// 1) 校准时间(默认实例)
|
||||
DataEyeAnalyticsAPI.CalibrateTimeWithNtp(ntpServer);
|
||||
|
||||
// 2) 设置超参数
|
||||
var superProperties = new Dictionary<string, object>
|
||||
{
|
||||
{ "channel", defaultChannel }
|
||||
};
|
||||
DataEyeAnalyticsAPI.SetSuperProperties(superProperties);
|
||||
|
||||
// 3) 开启自动采集
|
||||
DataEyeAnalyticsAPI.EnableAutoTrack(AUTO_TRACK_EVENTS.ALL);
|
||||
|
||||
// 如果上面没有抛异常,认为初始化成功
|
||||
_initialized = true;
|
||||
Debug.Log($"[BIManager] InitBI succeeded on attempt {attempt}");
|
||||
yield break;
|
||||
}
|
||||
catch (ArgumentNullException ane)
|
||||
{
|
||||
// 典型:DataEye 内部 instance 还没创建(appId 为 null) -> retry
|
||||
lastException = ane;
|
||||
Debug.LogWarning(
|
||||
$"[BIManager] DataEye not ready (attempt {attempt}), will retry. msg={ane.Message}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 其他异常,记录并决定是否重试
|
||||
lastException = ex;
|
||||
Debug.LogWarning($"[BIManager] InitBI attempt {attempt} threw: {ex.Message}");
|
||||
}
|
||||
|
||||
// 等待后重试
|
||||
yield return new WaitForSeconds(retryIntervalSeconds);
|
||||
}
|
||||
|
||||
// 重试用尽仍失败 —— 打日志(不再抛异常以免影响游戏流程)
|
||||
Debug.LogError("[BIManager] InitBI failed after retries. Last exception: " +
|
||||
(lastException?.ToString() ?? "null"));
|
||||
}
|
||||
finally
|
||||
{
|
||||
lock (_initLock)
|
||||
{
|
||||
_initializing = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ================= 通用埋点 =================
|
||||
public void TrackEvent(string eventName, Dictionary<string, object> properties = null)
|
||||
{
|
||||
// if (properties == null)
|
||||
// properties = new Dictionary<string, object>();
|
||||
//
|
||||
// DataEyeAnalyticsAPI.Track(eventName, properties);
|
||||
// DataEyeAnalyticsAPI.Flush();
|
||||
//
|
||||
// Debug.Log($"[BI] 事件上报: {eventName}, 属性={JsonConvert.SerializeObject(properties)}");
|
||||
}
|
||||
|
||||
// ================= 预制事件封装 =================
|
||||
|
||||
/// <summary>
|
||||
/// 上报广告事件
|
||||
/// </summary>
|
||||
/// <param name="eventName"></param>
|
||||
/// <param name="adType">Native,RewardedVideo,Banner,Interstitial,Splash</param>
|
||||
/// <param name="placementId">聚合广告位id</param>
|
||||
/// <param name="networkFirmId">广告网络ID</param>
|
||||
public void TrackAdEvent(string eventName, string adType, string placementId = null,
|
||||
string networkFirmId = null, double revenue = 0, string scene = null, string currency = "USD")
|
||||
{
|
||||
var props = new Dictionary<string, object>
|
||||
{
|
||||
{ "ad_type", adType }
|
||||
};
|
||||
|
||||
if (!string.IsNullOrEmpty(placementId))
|
||||
props["PlacementId"] = placementId;
|
||||
|
||||
if (!string.IsNullOrEmpty(networkFirmId))
|
||||
props["NetworkFirmId"] = networkFirmId;
|
||||
|
||||
if (revenue > 0)
|
||||
{
|
||||
props["Revenue"] = revenue;
|
||||
props["Ecpm"] = revenue * 1000;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(scene))
|
||||
props["scene"] = scene;
|
||||
|
||||
if (!string.IsNullOrEmpty(currency))
|
||||
props["Currency"] = currency;
|
||||
|
||||
|
||||
TrackEvent(eventName, props);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 上报内购事件
|
||||
/// </summary>
|
||||
/// <param name="revenue">收入</param>
|
||||
/// <param name="currency">币种</param>
|
||||
/// <param name="payType">支付方式 0=商店支付,1=三方支付</param>
|
||||
/// <param name="itemId">sku</param>
|
||||
/// <param name="status">order:下单 paid:付费成功 paid_err:扣款失败</param>
|
||||
/// <param name="itemName">商品名称</param>
|
||||
/// <param name="msg">如果遇到异常或相关情况,将err_msg进行上报</param>
|
||||
public void TrackPurchase(double revenue, string currency, string payType, string itemId,
|
||||
string status, string itemName = null, string msg = null)
|
||||
{
|
||||
var props = new Dictionary<string, object>
|
||||
{
|
||||
{ "Revenue", revenue },
|
||||
{ "Currency", currency },
|
||||
{ "type", payType },
|
||||
{ "item_id", itemId },
|
||||
{ "purchase_status", status }
|
||||
};
|
||||
|
||||
if (!string.IsNullOrEmpty(itemName))
|
||||
props["item_name"] = itemName;
|
||||
if (!string.IsNullOrEmpty(msg))
|
||||
props["msg"] = msg;
|
||||
|
||||
TrackEvent(BIEvent.PURCHASE, props);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 上报页面浏览
|
||||
/// </summary>
|
||||
public void TrackPageView(string pageName)
|
||||
{
|
||||
var props = new Dictionary<string, object>
|
||||
{
|
||||
{ "page_name", pageName } // 例如 "loading"、"game"
|
||||
};
|
||||
|
||||
TrackEvent(BIEvent.PAGE_VIEW, props);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AB 分组埋点
|
||||
/// </summary>
|
||||
public void TrackABConfig(int responseTime)
|
||||
{
|
||||
var props = new Dictionary<string, object>
|
||||
{
|
||||
{ "response_time", responseTime }
|
||||
};
|
||||
|
||||
TrackEvent(BIEvent.AB_CONFIG, props);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class BIEvent
|
||||
{
|
||||
// 自动采集(SDK 开启自动采集即可,不需要手动埋点)
|
||||
public const string APP_INSTALL = "app_install";
|
||||
public const string APP_START = "app_start";
|
||||
public const string APP_END = "app_end";
|
||||
public const string APP_VIEW = "app_view";
|
||||
public const string APP_CRASH = "app_crash";
|
||||
|
||||
// 内部预制事件
|
||||
public const string AD_REQUEST = "ad_request"; // 广告请求
|
||||
public const string AD_INVENTORY = "ad_inventory"; // 广告填充的时候
|
||||
public const string AD_IMP = "ad_imp"; // 广告展示
|
||||
public const string AD_CLICK = "ad_click"; // 广告点击
|
||||
|
||||
public const string PURCHASE = "purchase"; // 内购
|
||||
|
||||
// 页面相关
|
||||
public const string PAGE_VIEW = "page_view_customize";
|
||||
|
||||
// 其他业务事件(AB 测试等)
|
||||
public const string AB_CONFIG = "config"; // AB
|
||||
}
|
||||
@@ -1,100 +1,100 @@
|
||||
using Firebase;
|
||||
using Firebase.Analytics;
|
||||
using Firebase.Extensions;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BallKingdomCrush
|
||||
{
|
||||
public class FireBaseManger: MonoBehaviour
|
||||
{
|
||||
|
||||
public static bool IsReady { get; private set; } = false;
|
||||
|
||||
void Start()
|
||||
{
|
||||
FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task =>
|
||||
{
|
||||
if (task.Result == DependencyStatus.Available)
|
||||
{
|
||||
Debug.Log("Firebase 初始化成功");
|
||||
|
||||
// 启用 Analytics
|
||||
FirebaseAnalytics.SetAnalyticsCollectionEnabled(true);
|
||||
|
||||
IsReady = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Firebase 依赖错误: " + task.Result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Max 广告的收益上传Firebase
|
||||
/// </summary>
|
||||
/// <param name="adUnitId"></param>
|
||||
/// <param name="adInfo"></param>
|
||||
public static void OnAdRevenuePaid(string adUnitId, MaxSdkBase.AdInfo adInfo)
|
||||
{
|
||||
|
||||
if (!IsReady)
|
||||
{
|
||||
Debug.LogWarning("Firebase 未初始化完成,丢弃本次广告打点");
|
||||
return;
|
||||
}
|
||||
|
||||
double revenue = adInfo.Revenue; // 收入,单位是美元 (USD)
|
||||
string networkName = adInfo.NetworkName;
|
||||
string adFormat = adInfo.AdFormat;
|
||||
string adUnitIdentifier = adInfo.AdUnitIdentifier;
|
||||
|
||||
Debug.Log($"AppLovin 广告收入: {revenue} USD, 网络: {networkName}, 广告位: {adUnitId}");
|
||||
|
||||
// 上报到 Firebase
|
||||
var impressionParameters = new[] {
|
||||
new Firebase.Analytics.Parameter("ad_platform", "AppLovin"),
|
||||
new Firebase.Analytics.Parameter("ad_source", networkName),
|
||||
new Firebase.Analytics.Parameter("ad_unit_name", adUnitIdentifier),
|
||||
new Firebase.Analytics.Parameter("ad_format", adFormat),
|
||||
new Firebase.Analytics.Parameter("value", revenue),
|
||||
new Firebase.Analytics.Parameter("currency", "USD"), // All AppLovin revenue is sent in USD
|
||||
};
|
||||
Firebase.Analytics.FirebaseAnalytics.LogEvent("ad_impression", impressionParameters);
|
||||
|
||||
Debug.Log("已上报 ad_impression 事件到 Firebase");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 支付的收益上传Firebase
|
||||
/// </summary>
|
||||
public static void OnPayRevenueEvent(double value)
|
||||
{
|
||||
|
||||
if (!IsReady)
|
||||
{
|
||||
Debug.LogWarning("Firebase 未初始化完成,丢弃本次支付打点");
|
||||
return;
|
||||
}
|
||||
Debug.Log($"AppLovin 支付收入: {value} USD");
|
||||
|
||||
// var impressionParameters = new[] {
|
||||
// new Firebase.Analytics.Parameter("value", value),
|
||||
// new Firebase.Analytics.Parameter("currency", "USD"), // All AppLovin revenue is sent in USD
|
||||
// };
|
||||
//
|
||||
// Firebase.Analytics.FirebaseAnalytics.LogEvent("purchase", impressionParameters);
|
||||
|
||||
// 上报到 Firebase 保持标准格式
|
||||
var parameters = new[] {
|
||||
new Parameter(FirebaseAnalytics.ParameterValue, value),
|
||||
new Parameter(FirebaseAnalytics.ParameterCurrency, "USD")
|
||||
};
|
||||
FirebaseAnalytics.LogEvent(FirebaseAnalytics.EventPurchase, parameters);
|
||||
|
||||
|
||||
Debug.Log("已上报 purchase 事件到 Firebase");
|
||||
|
||||
}
|
||||
}
|
||||
// using Firebase;
|
||||
// using Firebase.Analytics;
|
||||
// using Firebase.Extensions;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BallKingdomCrush
|
||||
{
|
||||
public class FireBaseManger: MonoBehaviour
|
||||
{
|
||||
|
||||
public static bool IsReady { get; private set; } = false;
|
||||
|
||||
void Start()
|
||||
{
|
||||
// FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task =>
|
||||
// {
|
||||
// if (task.Result == DependencyStatus.Available)
|
||||
// {
|
||||
// Debug.Log("Firebase 初始化成功");
|
||||
//
|
||||
// // 启用 Analytics
|
||||
// FirebaseAnalytics.SetAnalyticsCollectionEnabled(true);
|
||||
//
|
||||
// IsReady = true;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Debug.LogError("Firebase 依赖错误: " + task.Result);
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Max 广告的收益上传Firebase
|
||||
/// </summary>
|
||||
/// <param name="adUnitId"></param>
|
||||
/// <param name="adInfo"></param>
|
||||
public static void OnAdRevenuePaid(string adUnitId, MaxSdkBase.AdInfo adInfo)
|
||||
{
|
||||
|
||||
if (!IsReady)
|
||||
{
|
||||
Debug.LogWarning("Firebase 未初始化完成,丢弃本次广告打点");
|
||||
return;
|
||||
}
|
||||
|
||||
double revenue = adInfo.Revenue; // 收入,单位是美元 (USD)
|
||||
string networkName = adInfo.NetworkName;
|
||||
string adFormat = adInfo.AdFormat;
|
||||
string adUnitIdentifier = adInfo.AdUnitIdentifier;
|
||||
|
||||
Debug.Log($"AppLovin 广告收入: {revenue} USD, 网络: {networkName}, 广告位: {adUnitId}");
|
||||
|
||||
// // 上报到 Firebase
|
||||
// var impressionParameters = new[] {
|
||||
// new Firebase.Analytics.Parameter("ad_platform", "AppLovin"),
|
||||
// new Firebase.Analytics.Parameter("ad_source", networkName),
|
||||
// new Firebase.Analytics.Parameter("ad_unit_name", adUnitIdentifier),
|
||||
// new Firebase.Analytics.Parameter("ad_format", adFormat),
|
||||
// new Firebase.Analytics.Parameter("value", revenue),
|
||||
// new Firebase.Analytics.Parameter("currency", "USD"), // All AppLovin revenue is sent in USD
|
||||
// };
|
||||
// Firebase.Analytics.FirebaseAnalytics.LogEvent("ad_impression", impressionParameters);
|
||||
|
||||
Debug.Log("已上报 ad_impression 事件到 Firebase");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 支付的收益上传Firebase
|
||||
/// </summary>
|
||||
public static void OnPayRevenueEvent(double value)
|
||||
{
|
||||
|
||||
if (!IsReady)
|
||||
{
|
||||
Debug.LogWarning("Firebase 未初始化完成,丢弃本次支付打点");
|
||||
return;
|
||||
}
|
||||
Debug.Log($"AppLovin 支付收入: {value} USD");
|
||||
|
||||
// var impressionParameters = new[] {
|
||||
// new Firebase.Analytics.Parameter("value", value),
|
||||
// new Firebase.Analytics.Parameter("currency", "USD"), // All AppLovin revenue is sent in USD
|
||||
// };
|
||||
//
|
||||
// Firebase.Analytics.FirebaseAnalytics.LogEvent("purchase", impressionParameters);
|
||||
|
||||
// 上报到 Firebase 保持标准格式
|
||||
// var parameters = new[] {
|
||||
// new Parameter(FirebaseAnalytics.ParameterValue, value),
|
||||
// new Parameter(FirebaseAnalytics.ParameterCurrency, "USD")
|
||||
// };
|
||||
// FirebaseAnalytics.LogEvent(FirebaseAnalytics.EventPurchase, parameters);
|
||||
|
||||
|
||||
Debug.Log("已上报 purchase 事件到 Firebase");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+167
-167
@@ -1,167 +1,167 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using SGModule.MarkdownKit;
|
||||
using SGModule.NetKit;
|
||||
using SGModule.Common.Helper;
|
||||
using UnityEngine;
|
||||
using BallKingdomCrush;
|
||||
using UNSDK;
|
||||
|
||||
public class LoveLegendRoot : MonoBehaviour
|
||||
{
|
||||
public void Awake()
|
||||
{
|
||||
#if UNITY_EDITOR || GAME_RELEASE
|
||||
GameObject.Find("IngameDebugConsole").SetActive(false);
|
||||
#endif
|
||||
SdkConfigMgr.Init();
|
||||
|
||||
MaxADKit.Init();
|
||||
OnLauncher();
|
||||
TrackKit.TrackLoginFunnel(LoginFunnelEventType.Bootstrap);
|
||||
|
||||
BuildGMTool();
|
||||
NetGmTool.Instance.Init();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static void OnLauncher()
|
||||
{
|
||||
Language.LoadLocalizedText();
|
||||
Language.Initialize();
|
||||
|
||||
AppObjConst.FrameGo = new GameObject($"{AppObjConst.FrameGoName}");
|
||||
AppObjConst.FrameGo.AddComponent<LoveLegendCore>();
|
||||
DontDestroyOnLoad(AppObjConst.FrameGo);
|
||||
App.InitApplication(SuperApplication.Instance);
|
||||
NetworkManager.haveSimCard = HasSIMCard();
|
||||
|
||||
MarkdownKit.Instance.LoadText("privacy", "https://official.piggyhydration.com/privacy.md");
|
||||
MarkdownKit.Instance.LoadText("user", "https://official.piggyhydration.com/user.md");
|
||||
}
|
||||
|
||||
private static string adInfoLabel = "";
|
||||
private static void BuildGMTool()
|
||||
{
|
||||
GMTool.Instance.AddItem(new GMToolItem(GUIType.Separator, () => "测试工具"));
|
||||
GMTool.Instance.AddItem(new GMToolItem(GUIType.Separator, () => "测试工具"));
|
||||
GMTool.Instance.AddItem(new GMToolItem(GUIType.Button,
|
||||
() => "清空签到记录",
|
||||
s =>
|
||||
{
|
||||
DataMgr.SignState.Value = new List<long>();
|
||||
}));
|
||||
GMTool.Instance.AddItem(new GMToolItem(GUIType.Button,
|
||||
() => "测试签到",
|
||||
s =>
|
||||
{
|
||||
DataMgr.SignState.Value.Add(GameHelper.GetNowTime() + (long)TimeSpan.FromDays(DataMgr.SignState.Value.Count).TotalSeconds);
|
||||
DataMgr.SignState.Save();
|
||||
}));
|
||||
GMTool.Instance.AddItem(new GMToolItem(GUIType.Button,
|
||||
() => "打开礼包界面",
|
||||
s =>
|
||||
{
|
||||
UICtrlDispatcher.Instance.Dispatch(UICtrlMsg.PackrewardUI_Open, true);
|
||||
}));
|
||||
GMTool.Instance.AddItem(new GMToolItem(GUIType.Button,
|
||||
() => "加广告次数+1",
|
||||
s =>
|
||||
{
|
||||
var adNums = AdExchangeManager.Instance.GetLookRewardADNum();
|
||||
adNums += 1;
|
||||
AdExchangeManager.Instance.SetLookRewardADNum(adNums);
|
||||
}));
|
||||
GMTool.Instance.AddItem(new GMToolItem(GUIType.Button,
|
||||
() => "加广告次数+10",
|
||||
s =>
|
||||
{
|
||||
var adNums = AdExchangeManager.Instance.GetLookRewardADNum();
|
||||
adNums += 10;
|
||||
AdExchangeManager.Instance.SetLookRewardADNum(adNums);
|
||||
}));
|
||||
GMTool.Instance.AddItem(new GMToolItem(GUIType.Button,
|
||||
() => "金币测试 +1000000",
|
||||
s =>
|
||||
{
|
||||
DataMgr.Coin.Value += 1000000;
|
||||
adInfoLabel += $"金币测试+1000000 当前金币: {DataMgr.Coin.Value}\n";
|
||||
}));
|
||||
GMTool.Instance.AddItem(new GMToolItem(GUIType.Button,
|
||||
() => "等级 +5",
|
||||
s =>
|
||||
{
|
||||
DataMgr.GameLevel.Value += 5;
|
||||
|
||||
adInfoLabel += $"等级 +5 当前等级: {DataMgr.GameLevel.Value}\n";
|
||||
}));
|
||||
GMTool.Instance.AddItem(new GMToolItem(GUIType.Button,
|
||||
() => "客户端日志上传",
|
||||
s =>
|
||||
{
|
||||
ErrorLogKit.Send("error", "客户端日志上传", "GM工具点击测试", SuperApplication.Instance.attribution);
|
||||
|
||||
}));
|
||||
GMTool.Instance.AddItem(new GMToolItem(GUIType.Button,
|
||||
() => "广告ID信息打印",
|
||||
s =>
|
||||
{
|
||||
adInfoLabel += $"Max token: {MaxADKit.SDKKey} \n 激励广告Id: {MaxADKit.rewardedADUnitID} \n 插屏广告Id: {MaxADKit.interstitialADUnitID} \n";
|
||||
|
||||
}));
|
||||
|
||||
GMTool.Instance.AddItem(new GMToolItem(GUIType.Label, () => $"{DataMgr.Ticket} 类型测试"));
|
||||
// 来显示 adInfoLabel 的内容
|
||||
GMTool.Instance.AddItem(new GMToolItem(GUIType.Label, () => adInfoLabel));
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static bool HasSIMCard()
|
||||
{
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
try
|
||||
{
|
||||
// 获取当前Activity
|
||||
AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
|
||||
AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
|
||||
|
||||
// 获取TelephonyManager
|
||||
AndroidJavaObject telephonyManager = currentActivity.Call<AndroidJavaObject>("getSystemService", "phone");
|
||||
|
||||
if (telephonyManager == null)
|
||||
{
|
||||
Debug.Log("无法获取TelephonyManager,可能设备不支持电话功能。");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 获取SIM卡状态
|
||||
int simState = telephonyManager.Call<int>("getSimState");
|
||||
|
||||
Debug.Log("simState-------" + simState);
|
||||
// 判断SIM卡状态
|
||||
switch (simState)
|
||||
{
|
||||
case 1: // SIM_STATE_ABSENT
|
||||
return false;
|
||||
case 2: // sim_STATE_PIN_REQUIRED
|
||||
case 3: // SIM_STATE_LOCKED
|
||||
case 4: // SIM_STATE_NETWORK_LOCKED
|
||||
case 5: // SIM_STATE_READY
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.LogError("检查SIM卡时出错: " + e.Message);
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using SGModule.MarkdownKit;
|
||||
using SGModule.NetKit;
|
||||
using SGModule.Common.Helper;
|
||||
using UnityEngine;
|
||||
using BallKingdomCrush;
|
||||
using UNSDK;
|
||||
|
||||
public class LoveLegendRoot : MonoBehaviour
|
||||
{
|
||||
public void Awake()
|
||||
{
|
||||
#if UNITY_EDITOR || GAME_RELEASE
|
||||
// GameObject.Find("IngameDebugConsole").SetActive(false);
|
||||
#endif
|
||||
SdkConfigMgr.Init();
|
||||
|
||||
MaxADKit.Init();
|
||||
OnLauncher();
|
||||
TrackKit.TrackLoginFunnel(LoginFunnelEventType.Bootstrap);
|
||||
|
||||
BuildGMTool();
|
||||
NetGmTool.Instance.Init();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static void OnLauncher()
|
||||
{
|
||||
Language.LoadLocalizedText();
|
||||
Language.Initialize();
|
||||
|
||||
AppObjConst.FrameGo = new GameObject($"{AppObjConst.FrameGoName}");
|
||||
AppObjConst.FrameGo.AddComponent<LoveLegendCore>();
|
||||
DontDestroyOnLoad(AppObjConst.FrameGo);
|
||||
App.InitApplication(SuperApplication.Instance);
|
||||
NetworkManager.haveSimCard = HasSIMCard();
|
||||
|
||||
MarkdownKit.Instance.LoadText("privacy", "https://official.piggyhydration.com/privacy.md");
|
||||
MarkdownKit.Instance.LoadText("user", "https://official.piggyhydration.com/user.md");
|
||||
}
|
||||
|
||||
private static string adInfoLabel = "";
|
||||
private static void BuildGMTool()
|
||||
{
|
||||
GMTool.Instance.AddItem(new GMToolItem(GUIType.Separator, () => "测试工具"));
|
||||
GMTool.Instance.AddItem(new GMToolItem(GUIType.Separator, () => "测试工具"));
|
||||
GMTool.Instance.AddItem(new GMToolItem(GUIType.Button,
|
||||
() => "清空签到记录",
|
||||
s =>
|
||||
{
|
||||
DataMgr.SignState.Value = new List<long>();
|
||||
}));
|
||||
GMTool.Instance.AddItem(new GMToolItem(GUIType.Button,
|
||||
() => "测试签到",
|
||||
s =>
|
||||
{
|
||||
DataMgr.SignState.Value.Add(GameHelper.GetNowTime() + (long)TimeSpan.FromDays(DataMgr.SignState.Value.Count).TotalSeconds);
|
||||
DataMgr.SignState.Save();
|
||||
}));
|
||||
GMTool.Instance.AddItem(new GMToolItem(GUIType.Button,
|
||||
() => "打开礼包界面",
|
||||
s =>
|
||||
{
|
||||
UICtrlDispatcher.Instance.Dispatch(UICtrlMsg.PackrewardUI_Open, true);
|
||||
}));
|
||||
GMTool.Instance.AddItem(new GMToolItem(GUIType.Button,
|
||||
() => "加广告次数+1",
|
||||
s =>
|
||||
{
|
||||
var adNums = AdExchangeManager.Instance.GetLookRewardADNum();
|
||||
adNums += 1;
|
||||
AdExchangeManager.Instance.SetLookRewardADNum(adNums);
|
||||
}));
|
||||
GMTool.Instance.AddItem(new GMToolItem(GUIType.Button,
|
||||
() => "加广告次数+10",
|
||||
s =>
|
||||
{
|
||||
var adNums = AdExchangeManager.Instance.GetLookRewardADNum();
|
||||
adNums += 10;
|
||||
AdExchangeManager.Instance.SetLookRewardADNum(adNums);
|
||||
}));
|
||||
GMTool.Instance.AddItem(new GMToolItem(GUIType.Button,
|
||||
() => "金币测试 +1000000",
|
||||
s =>
|
||||
{
|
||||
DataMgr.Coin.Value += 1000000;
|
||||
adInfoLabel += $"金币测试+1000000 当前金币: {DataMgr.Coin.Value}\n";
|
||||
}));
|
||||
GMTool.Instance.AddItem(new GMToolItem(GUIType.Button,
|
||||
() => "等级 +5",
|
||||
s =>
|
||||
{
|
||||
DataMgr.GameLevel.Value += 5;
|
||||
|
||||
adInfoLabel += $"等级 +5 当前等级: {DataMgr.GameLevel.Value}\n";
|
||||
}));
|
||||
GMTool.Instance.AddItem(new GMToolItem(GUIType.Button,
|
||||
() => "客户端日志上传",
|
||||
s =>
|
||||
{
|
||||
ErrorLogKit.Send("error", "客户端日志上传", "GM工具点击测试", SuperApplication.Instance.attribution);
|
||||
|
||||
}));
|
||||
GMTool.Instance.AddItem(new GMToolItem(GUIType.Button,
|
||||
() => "广告ID信息打印",
|
||||
s =>
|
||||
{
|
||||
adInfoLabel += $"Max token: {MaxADKit.SDKKey} \n 激励广告Id: {MaxADKit.rewardedADUnitID} \n 插屏广告Id: {MaxADKit.interstitialADUnitID} \n";
|
||||
|
||||
}));
|
||||
|
||||
GMTool.Instance.AddItem(new GMToolItem(GUIType.Label, () => $"{DataMgr.Ticket} 类型测试"));
|
||||
// 来显示 adInfoLabel 的内容
|
||||
GMTool.Instance.AddItem(new GMToolItem(GUIType.Label, () => adInfoLabel));
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static bool HasSIMCard()
|
||||
{
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
try
|
||||
{
|
||||
// 获取当前Activity
|
||||
AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
|
||||
AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
|
||||
|
||||
// 获取TelephonyManager
|
||||
AndroidJavaObject telephonyManager = currentActivity.Call<AndroidJavaObject>("getSystemService", "phone");
|
||||
|
||||
if (telephonyManager == null)
|
||||
{
|
||||
Debug.Log("无法获取TelephonyManager,可能设备不支持电话功能。");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 获取SIM卡状态
|
||||
int simState = telephonyManager.Call<int>("getSimState");
|
||||
|
||||
Debug.Log("simState-------" + simState);
|
||||
// 判断SIM卡状态
|
||||
switch (simState)
|
||||
{
|
||||
case 1: // SIM_STATE_ABSENT
|
||||
return false;
|
||||
case 2: // sim_STATE_PIN_REQUIRED
|
||||
case 3: // SIM_STATE_LOCKED
|
||||
case 4: // SIM_STATE_NETWORK_LOCKED
|
||||
case 5: // SIM_STATE_READY
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.LogError("检查SIM卡时出错: " + e.Message);
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,377 +1,378 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using FairyGUI;
|
||||
using FGUI.LG_secretAlbums;
|
||||
using FGUI.ZM_Common_01;
|
||||
using SGModule.Common.Helper;
|
||||
using SGModule.NetKit;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BallKingdomCrush
|
||||
{
|
||||
public class SecretAlbumsUI : BaseUI
|
||||
{
|
||||
private const int MaxVisibleCount = 6; // 一屏显示6个
|
||||
private const int PreloadCount = 2; // 上下各预加载一屏
|
||||
|
||||
private readonly Dictionary<int, bool> _fileIsExist = new();
|
||||
private readonly Dictionary<int, GLoader> activeLoaders = new();
|
||||
private SecretAlbumsUICtrl ctrl;
|
||||
private SecretAlbumsModel model;
|
||||
private com_scAlbums ui;
|
||||
|
||||
public SecretAlbumsUI(SecretAlbumsUICtrl ctrl) : base(ctrl)
|
||||
{
|
||||
uiName = UIConst.SecretAlbumsUI;
|
||||
this.ctrl = ctrl;
|
||||
}
|
||||
|
||||
protected override void SetUIInfo(UIInfo uiInfo)
|
||||
{
|
||||
uiInfo.packageName = "LG_secretAlbums";
|
||||
uiInfo.assetName = "com_scAlbums";
|
||||
uiInfo.layerType = UILayerType.Popup;
|
||||
uiInfo.isNeedOpenAnim = false;
|
||||
uiInfo.isNeedCloseAnim = false;
|
||||
uiInfo.isNeedUIMask = true;
|
||||
}
|
||||
|
||||
#region 生命周期
|
||||
protected override void OnInit()
|
||||
{
|
||||
//model = ModuleManager.Instance.GetModel(ModelConst.SecretAlbumsModel) as SecretAlbumsModel;
|
||||
// 初始化GLoader池,设置最大缓存数
|
||||
GLoaderPool.Instance.Init(null, 10, 464, 642);
|
||||
}
|
||||
|
||||
protected override void OnClose()
|
||||
{
|
||||
// 1. 解除 UI 对 Loader 的引用
|
||||
for (var i = 0; i < ui.sc_list.numChildren; i++)
|
||||
{
|
||||
var item = ui.sc_list.GetChildAt(i) as item_scalnums;
|
||||
if (item != null && item.com_pic.picture != null) item.com_pic.picture = null; // 清掉 GLoader 引用
|
||||
}
|
||||
|
||||
activeLoaders.Clear();
|
||||
_fileIsExist.Clear();
|
||||
|
||||
GLoaderPool.Instance.DisposeAll();
|
||||
|
||||
TextureHelper.ClearMaterialPool();
|
||||
|
||||
// 强制卸载未使用的资源
|
||||
// Resources.UnloadUnusedAssets();
|
||||
MemoryManager.CleanMemoryMonitor();
|
||||
}
|
||||
|
||||
protected override void OnBind()
|
||||
{
|
||||
ui = baseUI as FGUI.LG_secretAlbums.com_scAlbums;
|
||||
}
|
||||
|
||||
private List<SecretAlbums> _secretData = new List<SecretAlbums>();
|
||||
protected override void OnOpenBefore(object args)
|
||||
{
|
||||
if (Screen.safeArea.y != 0)
|
||||
{
|
||||
ui.btn_gold.y += 68;
|
||||
ui.btn_close.y += 68;
|
||||
ui.sc_list.y += 68;
|
||||
}
|
||||
|
||||
var eventName = GameHelper.IsAdModelOfPay() ? ADEventTrack.AD_Event : ADEventTrack.MaxPayEvent;
|
||||
TrackKit.SendEvent(eventName, ADEventTrack.Property.secret_albums_show);
|
||||
|
||||
_secretData = ConfigSystem.GetConfig<SecretAlbums>();
|
||||
InitView();
|
||||
}
|
||||
|
||||
protected override void OnOpen(object args)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnHide()
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnDisplay(object args)
|
||||
{
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 消息
|
||||
protected override void AddListener()
|
||||
{
|
||||
GameDispatcher.Instance.AddListener(GameMsg.UnlockSecretSuccess, UnlockSuccess);
|
||||
GameDispatcher.Instance.AddListener(GameMsg.Gold_refresh, set101);
|
||||
}
|
||||
protected override void RemoveListener()
|
||||
{
|
||||
GameDispatcher.Instance.RemoveListener(GameMsg.UnlockSecretSuccess, UnlockSuccess);
|
||||
GameDispatcher.Instance.RemoveListener(GameMsg.Gold_refresh, set101);
|
||||
}
|
||||
#endregion
|
||||
|
||||
void UnlockSuccess(object str = null)
|
||||
{
|
||||
ui.btn_gold.GetChild("text_gold").text = GameHelper.Get101Str();
|
||||
ui.sc_list.itemRenderer = ItemRender;
|
||||
ui.sc_list.numItems = _secretData.Count;
|
||||
}
|
||||
|
||||
private void set101(object obj)
|
||||
{
|
||||
ui.btn_gold.GetChild("text_gold").text = GameHelper.Get101Str();
|
||||
}
|
||||
|
||||
//初始化页面逻辑
|
||||
private void InitView()
|
||||
{
|
||||
ui.btn_gold.GetChild("text_gold").text = GameHelper.Get101Str();
|
||||
ui.btn_close.SetClick(CtrlCloseUI);
|
||||
|
||||
UnlockSuccess();
|
||||
|
||||
InitScroll();
|
||||
}
|
||||
|
||||
private void InitScroll()
|
||||
{
|
||||
ui.sc_list.scrollPane.onScroll.Add(OnScrollUpdate);
|
||||
ui.sc_list.scrollPane.onScrollEnd.Add(OnScrollEnd); // 保留结束时的整理
|
||||
|
||||
OnScrollEnd();
|
||||
}
|
||||
|
||||
// 滑动过程中实时更新
|
||||
private void OnScrollUpdate()
|
||||
{
|
||||
UpdateVisibleAndPreload();
|
||||
}
|
||||
|
||||
// 核心刷新逻辑
|
||||
private void UpdateVisibleAndPreload()
|
||||
{
|
||||
if (_secretData == null || _secretData.Count == 0) return;
|
||||
|
||||
var firstVisibleIndex = ui.sc_list.GetFirstChildInView();
|
||||
var lastVisibleIndex = Mathf.Min(firstVisibleIndex + MaxVisibleCount - 1, ui.sc_list.numItems - 1);
|
||||
|
||||
var startIndex = Mathf.Max(0, firstVisibleIndex - PreloadCount);
|
||||
var endIndex = Mathf.Min(ui.sc_list.numItems - 1, lastVisibleIndex + PreloadCount);
|
||||
|
||||
// 回收超出范围 loader
|
||||
var keysToRemove = new List<int>();
|
||||
foreach (var kv in activeLoaders)
|
||||
{
|
||||
var idx = kv.Key;
|
||||
if (idx < startIndex || idx > endIndex)
|
||||
{
|
||||
GLoaderPool.Instance.ReturnLoader(kv.Value);
|
||||
var oldItem = ui.sc_list.GetChildAt(idx) as item_scalnums;
|
||||
if (oldItem != null) oldItem.com_pic.picture = null;
|
||||
keysToRemove.Add(idx);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var k in keysToRemove) activeLoaders.Remove(k);
|
||||
|
||||
|
||||
// 分配 loader 并加载图片
|
||||
for (var i = startIndex; i <= endIndex; i++)
|
||||
{
|
||||
if (activeLoaders.ContainsKey(i)) continue;
|
||||
|
||||
var item = ui.sc_list.GetChildAt(i) as item_scalnums;
|
||||
if (item == null) continue;
|
||||
|
||||
if (item.com_pic.picture != null && !item.com_pic.picture.isDisposed)
|
||||
GLoaderPool.Instance.ReturnLoader(item.com_pic.picture);
|
||||
|
||||
var loader = GLoaderPool.Instance.GetLoader();
|
||||
item.com_pic.picture = loader;
|
||||
item.com_pic.AddChild(loader);
|
||||
loader.SetSize(item.com_pic.width, item.com_pic.height);
|
||||
|
||||
_fileIsExist.TryGetValue(i, out var value);
|
||||
if (!value)
|
||||
{
|
||||
var localPath = Path.Combine(TextureHelper.getResPath(), _secretData[i].Name + ".jpg");
|
||||
|
||||
if (File.Exists(localPath))
|
||||
{
|
||||
_fileIsExist[i] = true;
|
||||
Debug.Log($"[SetImgLoader] 本地存在,直接加载 {_secretData[i].Name}");
|
||||
CrazyAsyKit.StartCoroutine(TextureHelper.LoadTexture(_secretData[i].Name, loader, null,
|
||||
"SecretAlbums/"));
|
||||
}
|
||||
else
|
||||
{
|
||||
_fileIsExist[i] = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CrazyAsyKit.StartCoroutine(TextureHelper.LoadTexture(_secretData[i].Name, loader, null,
|
||||
"SecretAlbums/"));
|
||||
}
|
||||
|
||||
activeLoaders[i] = loader;
|
||||
}
|
||||
|
||||
// Debug.Log($"[ScrollUpdate] active loaders={activeLoaders.Count}, pool={GLoaderPool.Instance.GetPoolCount()}, inUse={GLoaderPool.Instance.GetInUseCount()}");
|
||||
}
|
||||
|
||||
private void OnScrollEnd()
|
||||
{
|
||||
if (_secretData == null || _secretData.Count == 0) return;
|
||||
|
||||
var firstVisibleIndex = ui.sc_list.GetFirstChildInView();
|
||||
var lastVisibleIndex = Mathf.Min(firstVisibleIndex + MaxVisibleCount - 1, ui.sc_list.numItems - 1);
|
||||
|
||||
var startIndex = Mathf.Max(0, firstVisibleIndex - PreloadCount);
|
||||
var endIndex = Mathf.Min(ui.sc_list.numItems - 1, lastVisibleIndex + PreloadCount);
|
||||
|
||||
// Debug.Log($"[ScrollEnd] start index={startIndex} end index={endIndex}");
|
||||
|
||||
|
||||
var tasks = new List<(GLoader loader, string fileName, Action<NTexture> callback, string folder, string localFolder)>();
|
||||
// 分配 loader 并加载图片
|
||||
for (var i = startIndex; i <= endIndex; i++)
|
||||
{
|
||||
_fileIsExist.TryGetValue(i, out var value);
|
||||
|
||||
if (value) continue;
|
||||
var item = ui.sc_list.GetChildAt(i) as item_scalnums;
|
||||
if (item == null) continue;
|
||||
if (item.com_pic.picture != null && !item.com_pic.picture.isDisposed)
|
||||
GLoaderPool.Instance.ReturnLoader(item.com_pic.picture);
|
||||
var loader = GLoaderPool.Instance.GetLoader();
|
||||
item.com_pic.picture = loader;
|
||||
item.com_pic.AddChild(loader);
|
||||
loader.SetSize(item.com_pic.width, item.com_pic.height);
|
||||
|
||||
var idx = i;
|
||||
tasks.Add((loader, _secretData[i].Name, texture =>
|
||||
{
|
||||
if (texture != null) _fileIsExist[idx] = true;
|
||||
}, "SecretAlbums/", FolderNames.SecretName));
|
||||
|
||||
activeLoaders[i] = loader;
|
||||
}
|
||||
|
||||
if (tasks.Count > 0)
|
||||
{
|
||||
TextureHelper.SetImgLoaders(tasks);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void ItemRender(int index, GObject obj)
|
||||
{
|
||||
var item = (item_scalnums)obj;
|
||||
|
||||
item.text_id.text = _secretData[index].id.ToString();
|
||||
|
||||
var isUnlock = DataMgr.SecretUnlockList.Value.Contains(index);
|
||||
|
||||
item.btn_unlock.pay_type.selectedIndex = _secretData[index].PayType;
|
||||
|
||||
if (_secretData[index].PayType == 0)
|
||||
item.btn_unlock.title = GameHelper.getPrice((decimal)_secretData[index].DiscountPrice);
|
||||
else if (_secretData[index].PayType == 1)
|
||||
item.btn_unlock.title = _secretData[index].GoldCoins.ToString();
|
||||
else if (_secretData[index].PayType == 2) item.btn_unlock.title = _secretData[index].AD + "AD";
|
||||
|
||||
if (isUnlock)
|
||||
{
|
||||
item.btn_unlock.pay_type.selectedIndex = 3;
|
||||
if (_secretData[index].SubscribeUnlock == 1)
|
||||
{
|
||||
item.vip.selectedIndex = 2;
|
||||
item.btn_unlock.pay_type.selectedIndex = 4;
|
||||
}
|
||||
item.btn_unlock.title = "GO";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_secretData[index].SubscribeUnlock == 1)
|
||||
{
|
||||
item.vip.selectedIndex = 1;
|
||||
item.btn_unlock.pay_type.selectedIndex = 4;
|
||||
}
|
||||
}
|
||||
|
||||
item.btn_null.SetClick(GotoNext);
|
||||
|
||||
item.un_lock.selectedIndex = isUnlock ? 1 : 0;
|
||||
|
||||
item.btn_unlock.SetClick(GotoNext);
|
||||
|
||||
item.peple_num.text = GetPepleNum(_secretData[index].Quantity).ToString();
|
||||
|
||||
item.hot.selectedIndex = _secretData[index].HotType;
|
||||
void GotoNext()
|
||||
{
|
||||
var da = _secretData;
|
||||
var data = new AlbumPreviewData
|
||||
{
|
||||
Index = index,
|
||||
State = _secretData[index].State,
|
||||
Price = _secretData[index].Price,
|
||||
PayType = _secretData[index].PayType,
|
||||
SubscribeUnlock = _secretData[index].SubscribeUnlock,
|
||||
DiscountPrice = _secretData[index].DiscountPrice,
|
||||
Name = _secretData[index].Name,
|
||||
Name2 = _secretData[index].Name2,
|
||||
GoldCoins = _secretData[index].GoldCoins,
|
||||
AD = _secretData[index].AD,
|
||||
CD = _secretData[index].CD
|
||||
};
|
||||
UICtrlDispatcher.Instance.Dispatch(UICtrlMsg.SecretAlbumsNextUI_Open, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private int GetPepleNum(float quantity)
|
||||
{
|
||||
// 获取当前时间
|
||||
DateTime now = DateTime.Now;
|
||||
|
||||
// 计算当天已经过去的分钟数(从凌晨 0 点开始算)
|
||||
int minutesPassedToday = now.Hour * 60 + now.Minute;
|
||||
|
||||
// 计算人数
|
||||
int num = Mathf.FloorToInt(quantity * minutesPassedToday);
|
||||
|
||||
return num;
|
||||
}
|
||||
}
|
||||
|
||||
public class AlbumPreviewData
|
||||
{
|
||||
public int[] State;
|
||||
public int Index;
|
||||
public string Name;
|
||||
public float Price;
|
||||
public int SubscribeUnlock;
|
||||
public int PayType;
|
||||
public float DiscountPrice;
|
||||
public string Name2;
|
||||
public int GoldCoins;
|
||||
public int AD;
|
||||
public int CD;
|
||||
}
|
||||
|
||||
public enum UnlockPayType
|
||||
{
|
||||
Pay = 0,
|
||||
Coin = 1,
|
||||
Ad = 2,
|
||||
None = 3,
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using FairyGUI;
|
||||
using FGUI.LG_secretAlbums;
|
||||
using FGUI.ZM_Common_01;
|
||||
using SGModule.Common.Helper;
|
||||
using SGModule.NetKit;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BallKingdomCrush
|
||||
{
|
||||
public class SecretAlbumsUI : BaseUI
|
||||
{
|
||||
private const int MaxVisibleCount = 6; // 一屏显示6个
|
||||
private const int PreloadCount = 2; // 上下各预加载一屏
|
||||
|
||||
private readonly Dictionary<int, bool> _fileIsExist = new();
|
||||
private readonly Dictionary<int, GLoader> activeLoaders = new();
|
||||
private SecretAlbumsUICtrl ctrl;
|
||||
private SecretAlbumsModel model;
|
||||
private com_scAlbums ui;
|
||||
|
||||
public SecretAlbumsUI(SecretAlbumsUICtrl ctrl) : base(ctrl)
|
||||
{
|
||||
uiName = UIConst.SecretAlbumsUI;
|
||||
this.ctrl = ctrl;
|
||||
}
|
||||
|
||||
protected override void SetUIInfo(UIInfo uiInfo)
|
||||
{
|
||||
uiInfo.packageName = "LG_secretAlbums";
|
||||
uiInfo.assetName = "com_scAlbums";
|
||||
uiInfo.layerType = UILayerType.Popup;
|
||||
uiInfo.isNeedOpenAnim = false;
|
||||
uiInfo.isNeedCloseAnim = false;
|
||||
uiInfo.isNeedUIMask = true;
|
||||
}
|
||||
|
||||
#region 生命周期
|
||||
protected override void OnInit()
|
||||
{
|
||||
//model = ModuleManager.Instance.GetModel(ModelConst.SecretAlbumsModel) as SecretAlbumsModel;
|
||||
// 初始化GLoader池,设置最大缓存数
|
||||
GLoaderPool.Instance.Init(null, 10, 464, 642);
|
||||
}
|
||||
|
||||
protected override void OnClose()
|
||||
{
|
||||
// 1. 解除 UI 对 Loader 的引用
|
||||
for (var i = 0; i < ui.sc_list.numChildren; i++)
|
||||
{
|
||||
var item = ui.sc_list.GetChildAt(i) as item_scalnums;
|
||||
if (item != null && item.com_pic.picture != null) item.com_pic.picture = null; // 清掉 GLoader 引用
|
||||
}
|
||||
|
||||
activeLoaders.Clear();
|
||||
_fileIsExist.Clear();
|
||||
|
||||
GLoaderPool.Instance.DisposeAll();
|
||||
|
||||
TextureHelper.ClearMaterialPool();
|
||||
|
||||
// 强制卸载未使用的资源
|
||||
// Resources.UnloadUnusedAssets();
|
||||
MemoryManager.CleanMemoryMonitor();
|
||||
}
|
||||
|
||||
protected override void OnBind()
|
||||
{
|
||||
ui = baseUI as FGUI.LG_secretAlbums.com_scAlbums;
|
||||
}
|
||||
|
||||
private List<SecretAlbums> _secretData = new List<SecretAlbums>();
|
||||
private List<SecretAlbums> _secretData1 = new List<SecretAlbums>();
|
||||
protected override void OnOpenBefore(object args)
|
||||
{
|
||||
if (Screen.safeArea.y != 0)
|
||||
{
|
||||
ui.btn_gold.y += 68;
|
||||
ui.btn_close.y += 68;
|
||||
ui.sc_list.y += 68;
|
||||
}
|
||||
|
||||
var eventName = GameHelper.IsAdModelOfPay() ? ADEventTrack.AD_Event : ADEventTrack.MaxPayEvent;
|
||||
TrackKit.SendEvent(eventName, ADEventTrack.Property.secret_albums_show);
|
||||
|
||||
_secretData = ConfigSystem.GetConfig<SecretAlbums>();
|
||||
InitView();
|
||||
}
|
||||
|
||||
protected override void OnOpen(object args)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnHide()
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnDisplay(object args)
|
||||
{
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 消息
|
||||
protected override void AddListener()
|
||||
{
|
||||
GameDispatcher.Instance.AddListener(GameMsg.UnlockSecretSuccess, UnlockSuccess);
|
||||
GameDispatcher.Instance.AddListener(GameMsg.Gold_refresh, set101);
|
||||
}
|
||||
protected override void RemoveListener()
|
||||
{
|
||||
GameDispatcher.Instance.RemoveListener(GameMsg.UnlockSecretSuccess, UnlockSuccess);
|
||||
GameDispatcher.Instance.RemoveListener(GameMsg.Gold_refresh, set101);
|
||||
}
|
||||
#endregion
|
||||
|
||||
void UnlockSuccess(object str = null)
|
||||
{
|
||||
ui.btn_gold.GetChild("text_gold").text = GameHelper.Get101Str();
|
||||
ui.sc_list.itemRenderer = ItemRender;
|
||||
ui.sc_list.numItems = _secretData.Count;
|
||||
}
|
||||
|
||||
private void set101(object obj)
|
||||
{
|
||||
ui.btn_gold.GetChild("text_gold").text = GameHelper.Get101Str();
|
||||
}
|
||||
|
||||
//初始化页面逻辑
|
||||
private void InitView()
|
||||
{
|
||||
ui.btn_gold.GetChild("text_gold").text = GameHelper.Get101Str();
|
||||
ui.btn_close.SetClick(CtrlCloseUI);
|
||||
|
||||
UnlockSuccess();
|
||||
|
||||
InitScroll();
|
||||
}
|
||||
|
||||
private void InitScroll()
|
||||
{
|
||||
ui.sc_list.scrollPane.onScroll.Add(OnScrollUpdate);
|
||||
ui.sc_list.scrollPane.onScrollEnd.Add(OnScrollEnd); // 保留结束时的整理
|
||||
|
||||
OnScrollEnd();
|
||||
}
|
||||
|
||||
// 滑动过程中实时更新
|
||||
private void OnScrollUpdate()
|
||||
{
|
||||
UpdateVisibleAndPreload();
|
||||
}
|
||||
|
||||
// 核心刷新逻辑
|
||||
private void UpdateVisibleAndPreload()
|
||||
{
|
||||
if (_secretData == null || _secretData.Count == 0) return;
|
||||
|
||||
var firstVisibleIndex = ui.sc_list.GetFirstChildInView();
|
||||
var lastVisibleIndex = Mathf.Min(firstVisibleIndex + MaxVisibleCount - 1, ui.sc_list.numItems - 1);
|
||||
|
||||
var startIndex = Mathf.Max(0, firstVisibleIndex - PreloadCount);
|
||||
var endIndex = Mathf.Min(ui.sc_list.numItems - 1, lastVisibleIndex + PreloadCount);
|
||||
|
||||
// 回收超出范围 loader
|
||||
var keysToRemove = new List<int>();
|
||||
foreach (var kv in activeLoaders)
|
||||
{
|
||||
var idx = kv.Key;
|
||||
if (idx < startIndex || idx > endIndex)
|
||||
{
|
||||
GLoaderPool.Instance.ReturnLoader(kv.Value);
|
||||
var oldItem = ui.sc_list.GetChildAt(idx) as item_scalnums;
|
||||
if (oldItem != null) oldItem.com_pic.picture = null;
|
||||
keysToRemove.Add(idx);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var k in keysToRemove) activeLoaders.Remove(k);
|
||||
|
||||
|
||||
// 分配 loader 并加载图片
|
||||
for (var i = startIndex; i <= endIndex; i++)
|
||||
{
|
||||
if (activeLoaders.ContainsKey(i)) continue;
|
||||
|
||||
var item = ui.sc_list.GetChildAt(i) as item_scalnums;
|
||||
if (item == null) continue;
|
||||
|
||||
if (item.com_pic.picture != null && !item.com_pic.picture.isDisposed)
|
||||
GLoaderPool.Instance.ReturnLoader(item.com_pic.picture);
|
||||
|
||||
var loader = GLoaderPool.Instance.GetLoader();
|
||||
item.com_pic.picture = loader;
|
||||
item.com_pic.AddChild(loader);
|
||||
loader.SetSize(item.com_pic.width, item.com_pic.height);
|
||||
|
||||
_fileIsExist.TryGetValue(i, out var value);
|
||||
if (!value)
|
||||
{
|
||||
var localPath = Path.Combine(TextureHelper.getResPath(), _secretData[i].Name + ".jpg");
|
||||
|
||||
if (File.Exists(localPath))
|
||||
{
|
||||
_fileIsExist[i] = true;
|
||||
Debug.Log($"[SetImgLoader] 本地存在,直接加载 {_secretData[i].Name}");
|
||||
CrazyAsyKit.StartCoroutine(TextureHelper.LoadTexture(_secretData[i].Name, loader, null,
|
||||
"SecretAlbums/"));
|
||||
}
|
||||
else
|
||||
{
|
||||
_fileIsExist[i] = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CrazyAsyKit.StartCoroutine(TextureHelper.LoadTexture(_secretData[i].Name, loader, null,
|
||||
"SecretAlbums/"));
|
||||
}
|
||||
|
||||
activeLoaders[i] = loader;
|
||||
}
|
||||
|
||||
// Debug.Log($"[ScrollUpdate] active loaders={activeLoaders.Count}, pool={GLoaderPool.Instance.GetPoolCount()}, inUse={GLoaderPool.Instance.GetInUseCount()}");
|
||||
}
|
||||
|
||||
private void OnScrollEnd()
|
||||
{
|
||||
if (_secretData == null || _secretData.Count == 0) return;
|
||||
|
||||
var firstVisibleIndex = ui.sc_list.GetFirstChildInView();
|
||||
var lastVisibleIndex = Mathf.Min(firstVisibleIndex + MaxVisibleCount - 1, ui.sc_list.numItems - 1);
|
||||
|
||||
var startIndex = Mathf.Max(0, firstVisibleIndex - PreloadCount);
|
||||
var endIndex = Mathf.Min(ui.sc_list.numItems - 1, lastVisibleIndex + PreloadCount);
|
||||
|
||||
// Debug.Log($"[ScrollEnd] start index={startIndex} end index={endIndex}");
|
||||
|
||||
|
||||
var tasks = new List<(GLoader loader, string fileName, Action<NTexture> callback, string folder, string localFolder)>();
|
||||
// 分配 loader 并加载图片
|
||||
for (var i = startIndex; i <= endIndex; i++)
|
||||
{
|
||||
_fileIsExist.TryGetValue(i, out var value);
|
||||
|
||||
if (value) continue;
|
||||
var item = ui.sc_list.GetChildAt(i) as item_scalnums;
|
||||
if (item == null) continue;
|
||||
if (item.com_pic.picture != null && !item.com_pic.picture.isDisposed)
|
||||
GLoaderPool.Instance.ReturnLoader(item.com_pic.picture);
|
||||
var loader = GLoaderPool.Instance.GetLoader();
|
||||
item.com_pic.picture = loader;
|
||||
item.com_pic.AddChild(loader);
|
||||
loader.SetSize(item.com_pic.width, item.com_pic.height);
|
||||
|
||||
var idx = i;
|
||||
tasks.Add((loader, _secretData[i].Name, texture =>
|
||||
{
|
||||
if (texture != null) _fileIsExist[idx] = true;
|
||||
}, "SecretAlbums/", FolderNames.SecretName));
|
||||
|
||||
activeLoaders[i] = loader;
|
||||
}
|
||||
|
||||
if (tasks.Count > 0)
|
||||
{
|
||||
TextureHelper.SetImgLoaders(tasks);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void ItemRender(int index, GObject obj)
|
||||
{
|
||||
var item = (item_scalnums)obj;
|
||||
|
||||
item.text_id.text = _secretData[index].id.ToString();
|
||||
|
||||
var isUnlock = DataMgr.SecretUnlockList.Value.Contains(index);
|
||||
|
||||
item.btn_unlock.pay_type.selectedIndex = _secretData[index].PayType;
|
||||
|
||||
if (_secretData[index].PayType == 0)
|
||||
item.btn_unlock.title = GameHelper.getPrice((decimal)_secretData[index].DiscountPrice);
|
||||
else if (_secretData[index].PayType == 1)
|
||||
item.btn_unlock.title = _secretData[index].GoldCoins.ToString();
|
||||
else if (_secretData[index].PayType == 2) item.btn_unlock.title = _secretData[index].AD + "AD";
|
||||
|
||||
if (isUnlock)
|
||||
{
|
||||
item.btn_unlock.pay_type.selectedIndex = 3;
|
||||
if (_secretData[index].SubscribeUnlock == 1)
|
||||
{
|
||||
item.vip.selectedIndex = 2;
|
||||
item.btn_unlock.pay_type.selectedIndex = 4;
|
||||
}
|
||||
item.btn_unlock.title = "GO";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_secretData[index].SubscribeUnlock == 1)
|
||||
{
|
||||
item.vip.selectedIndex = 1;
|
||||
item.btn_unlock.pay_type.selectedIndex = 4;
|
||||
}
|
||||
}
|
||||
|
||||
item.btn_null.SetClick(GotoNext);
|
||||
|
||||
item.un_lock.selectedIndex = isUnlock ? 1 : 0;
|
||||
|
||||
item.btn_unlock.SetClick(GotoNext);
|
||||
|
||||
item.peple_num.text = GetPepleNum(_secretData[index].Quantity).ToString();
|
||||
|
||||
item.hot.selectedIndex = _secretData[index].HotType;
|
||||
void GotoNext()
|
||||
{
|
||||
var da = _secretData;
|
||||
var data = new AlbumPreviewData
|
||||
{
|
||||
Index = index,
|
||||
State = _secretData[index].State,
|
||||
Price = _secretData[index].Price,
|
||||
PayType = _secretData[index].PayType,
|
||||
SubscribeUnlock = _secretData[index].SubscribeUnlock,
|
||||
DiscountPrice = _secretData[index].DiscountPrice,
|
||||
Name = _secretData[index].Name,
|
||||
Name2 = _secretData[index].Name2,
|
||||
GoldCoins = _secretData[index].GoldCoins,
|
||||
AD = _secretData[index].AD,
|
||||
CD = _secretData[index].CD
|
||||
};
|
||||
UICtrlDispatcher.Instance.Dispatch(UICtrlMsg.SecretAlbumsNextUI_Open, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private int GetPepleNum(float quantity)
|
||||
{
|
||||
// 获取当前时间
|
||||
DateTime now = DateTime.Now;
|
||||
|
||||
// 计算当天已经过去的分钟数(从凌晨 0 点开始算)
|
||||
int minutesPassedToday = now.Hour * 60 + now.Minute;
|
||||
|
||||
// 计算人数
|
||||
int num = Mathf.FloorToInt(quantity * minutesPassedToday);
|
||||
|
||||
return num;
|
||||
}
|
||||
}
|
||||
|
||||
public class AlbumPreviewData
|
||||
{
|
||||
public int[] State;
|
||||
public int Index;
|
||||
public string Name;
|
||||
public float Price;
|
||||
public int SubscribeUnlock;
|
||||
public int PayType;
|
||||
public float DiscountPrice;
|
||||
public string Name2;
|
||||
public int GoldCoins;
|
||||
public int AD;
|
||||
public int CD;
|
||||
}
|
||||
|
||||
public enum UnlockPayType
|
||||
{
|
||||
Pay = 0,
|
||||
Coin = 1,
|
||||
Ad = 2,
|
||||
None = 3,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,150 +1,178 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using IgnoreOPS;
|
||||
using SGModule.Common.Extensions;
|
||||
using SGModule.Common.Helper;
|
||||
using SGModule.ConfigLoader;
|
||||
using SGModule.NetKit;
|
||||
using UnityEngine;
|
||||
using CommonModel = IgnoreOPS.CommonModel;
|
||||
|
||||
namespace BallKingdomCrush
|
||||
{
|
||||
public class ConfigSystem : BaseSystem
|
||||
{
|
||||
public static string web_through_str;
|
||||
|
||||
public ConfigSystem(bool isAutoInit = true)
|
||||
{
|
||||
if (isAutoInit)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed override void Init()
|
||||
{
|
||||
base.Init();
|
||||
AddListener();
|
||||
}
|
||||
|
||||
private void AddListener()
|
||||
{
|
||||
NetworkDispatcher.Instance.AddListener(NetworkMsg.GetConfig, OnGetConfig);
|
||||
}
|
||||
|
||||
private void RemoveListener()
|
||||
{
|
||||
NetworkDispatcher.Instance.RemoveListener(NetworkMsg.GetConfig, OnGetConfig);
|
||||
}
|
||||
|
||||
private void OnGetConfig(object obj)
|
||||
{
|
||||
TrackKit.TrackLoginFunnel(LoginFunnelEventType.LoadBegin); //加载开始打点
|
||||
|
||||
var loginModel = LoginKit.Instance.LoginModel;
|
||||
Log.Info("Config", $"服务器传过来的配置表:{loginModel.Setting}");
|
||||
ConfigLoader.Instance.Init(new ConfigInitOptions
|
||||
{
|
||||
Setting = loginModel.Setting,
|
||||
CdnUrl = loginModel.CdnURL,
|
||||
OnComplete = state =>
|
||||
{
|
||||
Debug.Log($"配置加载状态{state}");
|
||||
if (state == ConfigLoaderState.Successful)
|
||||
{
|
||||
ReloadConfig();
|
||||
}
|
||||
},
|
||||
OnError = (errorName, message) => { Debug.LogError($"配置解析错误 {errorName} 错误信息:{message}"); },
|
||||
OnHandleUnmarkedConfig = ParseGameConfig
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 重新加载配置
|
||||
/// </summary>
|
||||
/// <param name="json"></param>
|
||||
private void ReloadConfig()
|
||||
{
|
||||
TrackKit.TrackLoginFunnel(LoginFunnelEventType.LoadFinish); //加载完成打点
|
||||
|
||||
ParseGameConfig();
|
||||
TextureHelper.imgUrl = LoginKit.Instance.LoginModel.CdnURL + "/" + ConfigSystem.GetCommonConf().ResVersion + "/";
|
||||
LiveVideoManager.videoBaseUrl = LoginKit.Instance.LoginModel.CdnURL + "/" + ConfigSystem.GetCommonConf().ResVersion + "/";
|
||||
UICtrlDispatcher.Instance.Dispatch(UICtrlMsg.NetLoadingUI_Close);
|
||||
AppDispatcher.Instance.Dispatch(AppMsg.LoginInit);
|
||||
CtrlDispatcher.Instance.Dispatch(CtrlMsg.Game_StartBefore);
|
||||
SaveingPotHelper.ResetHistory();
|
||||
}
|
||||
|
||||
|
||||
#region 游戏配置
|
||||
|
||||
private void ParseGameConfig()
|
||||
{
|
||||
var gameConfigModel = new GameConfigModel();
|
||||
foreach (var key in ConfigLoader.Instance.GetJsonKeys())
|
||||
{
|
||||
if (!key.StartsWith("GameBoard"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// 提取 boardIndex
|
||||
var boardIndex = 1;
|
||||
var parts = key.Split('_');
|
||||
if (parts.Length > 1 && int.TryParse(parts[1], out var parsed))
|
||||
{
|
||||
boardIndex = parsed;
|
||||
}
|
||||
|
||||
// 获取 json 并反序列化
|
||||
if (ConfigLoader.Instance.TryGetJsonValue(key, out var gameboardJson))
|
||||
{
|
||||
try
|
||||
{
|
||||
var gameBoards = gameboardJson.As<List<GameBoard>>();
|
||||
if (gameBoards != null)
|
||||
{
|
||||
gameConfigModel.game_conf[boardIndex] = gameBoards;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.ConfigLoader.Warning($"GameBoard 配置 {key} 反序列化为空");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ConfigLoader.Error($"GameBoard 配置 {key} 反序列化失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ConfigLoader.Instance.AddConfig(gameConfigModel);
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
public static CommonModel GetCommonConf()
|
||||
{
|
||||
return ConfigLoader.Instance.GetConfig<CommonModel>();
|
||||
}
|
||||
|
||||
public static List<T> GetConfig<T>() where T : class
|
||||
{
|
||||
return ConfigLoader.Instance.GetConfig<List<T>>() ?? new List<T>();
|
||||
}
|
||||
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
base.Dispose();
|
||||
RemoveListener();
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using IgnoreOPS;
|
||||
using SGModule.Common.Extensions;
|
||||
using SGModule.Common.Helper;
|
||||
using SGModule.ConfigLoader;
|
||||
using SGModule.NetKit;
|
||||
using UnityEngine;
|
||||
using CommonModel = IgnoreOPS.CommonModel;
|
||||
|
||||
namespace BallKingdomCrush
|
||||
{
|
||||
public class ConfigSystem : BaseSystem
|
||||
{
|
||||
public static string web_through_str;
|
||||
|
||||
public ConfigSystem(bool isAutoInit = true)
|
||||
{
|
||||
if (isAutoInit)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed override void Init()
|
||||
{
|
||||
base.Init();
|
||||
AddListener();
|
||||
}
|
||||
|
||||
private void AddListener()
|
||||
{
|
||||
NetworkDispatcher.Instance.AddListener(NetworkMsg.GetConfig, OnGetConfig);
|
||||
}
|
||||
|
||||
private void RemoveListener()
|
||||
{
|
||||
NetworkDispatcher.Instance.RemoveListener(NetworkMsg.GetConfig, OnGetConfig);
|
||||
}
|
||||
|
||||
private void OnGetConfig(object obj)
|
||||
{
|
||||
TrackKit.TrackLoginFunnel(LoginFunnelEventType.LoadBegin); //加载开始打点
|
||||
|
||||
var loginModel = LoginKit.Instance.LoginModel;
|
||||
Log.Info("Config", $"服务器传过来的配置表:{loginModel.Setting}");
|
||||
ConfigLoader.Instance.Init(new ConfigInitOptions
|
||||
{
|
||||
Setting = loginModel.Setting,
|
||||
CdnUrl = loginModel.CdnURL,
|
||||
OnComplete = state =>
|
||||
{
|
||||
Debug.Log($"配置加载状态{state}");
|
||||
if (state == ConfigLoaderState.Successful)
|
||||
{
|
||||
ReloadConfig();
|
||||
}
|
||||
},
|
||||
OnError = (errorName, message) => { Debug.LogError($"配置解析错误 {errorName} 错误信息:{message}"); },
|
||||
OnHandleUnmarkedConfig = ParseGameConfig
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 重新加载配置
|
||||
/// </summary>
|
||||
/// <param name="json"></param>
|
||||
|
||||
private void ReloadConfig()
|
||||
{
|
||||
var CdnURL = "https://asserts.minskyfun.top";
|
||||
|
||||
TrackKit.TrackLoginFunnel(LoginFunnelEventType.LoadFinish); //加载完成打点
|
||||
|
||||
ParseGameConfig();
|
||||
TextureHelper.imgUrl = CdnURL + "/" + ConfigSystem.GetCommonConf().ResVersion + "/";
|
||||
LiveVideoManager.videoBaseUrl = CdnURL + "/" + ConfigSystem.GetCommonConf().ResVersion + "/";
|
||||
UICtrlDispatcher.Instance.Dispatch(UICtrlMsg.NetLoadingUI_Close);
|
||||
AppDispatcher.Instance.Dispatch(AppMsg.LoginInit);
|
||||
CtrlDispatcher.Instance.Dispatch(CtrlMsg.Game_StartBefore);
|
||||
SaveingPotHelper.ResetHistory();
|
||||
}
|
||||
|
||||
|
||||
#region 游戏配置
|
||||
|
||||
private void ParseGameConfig()
|
||||
{
|
||||
var gameConfigModel = new GameConfigModel();
|
||||
foreach (var key in ConfigLoader.Instance.GetJsonKeys())
|
||||
{
|
||||
if (!key.StartsWith("GameBoard"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// 提取 boardIndex
|
||||
var boardIndex = 1;
|
||||
var parts = key.Split('_');
|
||||
if (parts.Length > 1 && int.TryParse(parts[1], out var parsed))
|
||||
{
|
||||
boardIndex = parsed;
|
||||
}
|
||||
|
||||
// 获取 json 并反序列化
|
||||
if (ConfigLoader.Instance.TryGetJsonValue(key, out var gameboardJson))
|
||||
{
|
||||
try
|
||||
{
|
||||
var gameBoards = gameboardJson.As<List<GameBoard>>();
|
||||
if (gameBoards != null)
|
||||
{
|
||||
gameConfigModel.game_conf[boardIndex] = gameBoards;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.ConfigLoader.Warning($"GameBoard 配置 {key} 反序列化为空");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ConfigLoader.Error($"GameBoard 配置 {key} 反序列化失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ConfigLoader.Instance.AddConfig(gameConfigModel);
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
public static CommonModel GetCommonConf()
|
||||
{
|
||||
return ConfigLoader.Instance.GetConfig<CommonModel>();
|
||||
}
|
||||
|
||||
public static List<T> GetConfig<T>() where T : class
|
||||
{
|
||||
return ConfigLoader.Instance.GetConfig<List<T>>() ?? new List<T>();
|
||||
}
|
||||
|
||||
private static List<T> GetConfigWithOrganicFallback<T, TOrganic>() where T : class
|
||||
{
|
||||
if (GameHelper.IsGiftSwitch() && SuperApplication.Instance.attribution == "organic")
|
||||
{
|
||||
var organicConfig = ConfigLoader.Instance.GetConfig<List<TOrganic>>();
|
||||
if (organicConfig != null)
|
||||
{
|
||||
return organicConfig.Cast<T>().ToList();
|
||||
}
|
||||
}
|
||||
|
||||
return GetConfig<T>();
|
||||
}
|
||||
|
||||
public static List<Live> GetLiveConfig()
|
||||
{
|
||||
return GetConfigWithOrganicFallback<Live, Live_A>();
|
||||
}
|
||||
|
||||
public static List<SecretAlbums> GetSecretAlbumsConfig()
|
||||
{
|
||||
return GetConfigWithOrganicFallback<SecretAlbums, SecretAlbums_A>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
base.Dispose();
|
||||
RemoveListener();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,96 +1,101 @@
|
||||
using System;
|
||||
using IgnoreOPS;
|
||||
using SGModule.Common.Extensions;
|
||||
using SGModule.Common.Helper;
|
||||
using SGModule.NetKit;
|
||||
|
||||
namespace BallKingdomCrush {
|
||||
public class LoginSystem : BaseSystem {
|
||||
private int loginCount = 0;
|
||||
|
||||
private bool _isLogin = false;
|
||||
|
||||
|
||||
private TimerTask timerTask = null;
|
||||
|
||||
public LoginSystem(bool isAutoInit = true) {
|
||||
if (isAutoInit) {
|
||||
Init();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed override void Init() {
|
||||
base.Init();
|
||||
InitData();
|
||||
AddListener();
|
||||
}
|
||||
|
||||
private void InitData() {
|
||||
}
|
||||
|
||||
private void AddListener() {
|
||||
NetworkDispatcher.Instance.AddListener(NetworkMsg.Login, RequestLogin);
|
||||
}
|
||||
|
||||
private void RemoveListener() {
|
||||
NetworkDispatcher.Instance.RemoveListener(NetworkMsg.Login, RequestLogin);
|
||||
}
|
||||
|
||||
private void RequestLogin(object obj = null) {
|
||||
|
||||
// if (!GameHelper.IsConnect())
|
||||
// {
|
||||
// LoginFail();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
if (_isLogin) return;
|
||||
_isLogin = true;
|
||||
|
||||
TrackKit.TrackLoginFunnel(LoginFunnelEventType.LoginSend);
|
||||
UICtrlDispatcher.Instance.Dispatch(UICtrlMsg.NetworkErrorTipsUI_Open);
|
||||
Log.Info("login request", $"attribution: {SuperApplication.Instance.attribution}, haveSimCard: {NetworkManager.haveSimCard}");
|
||||
LoginKit.Instance.LoginRequest(SuperApplication.Instance.attribution.ToLower(), NetworkManager.haveSimCard, (isSuccess, loginData) => {
|
||||
TrackKit.TrackLoginFunnel(LoginFunnelEventType.LoginRecv, isSuccess ? "success" : "fail");
|
||||
|
||||
UICtrlDispatcher.Instance.Dispatch(UICtrlMsg.NetworkErrorTipsUI_Close);
|
||||
|
||||
if (isSuccess)
|
||||
{
|
||||
// AB上传 BI
|
||||
BIManager.Instance.TrackABConfig(loginData.IsMagic ? 30 : 15);
|
||||
|
||||
TextureHelper.imgUrl = loginData.CdnURL + "/encrypt/image/";
|
||||
LiveVideoManager.videoBaseUrl = loginData.CdnURL + "/encrypt/video/";
|
||||
|
||||
DateTimeManager.Instance.SetServerCurrTimestamp(loginData.LoginTime);
|
||||
|
||||
NetworkDispatcher.Instance.Dispatch(NetworkMsg.GetPlayData);
|
||||
|
||||
MaxADKit.SetUserID(loginData.Uid.As<string>());
|
||||
}
|
||||
else
|
||||
{
|
||||
LoginFail();
|
||||
}
|
||||
});
|
||||
// }
|
||||
}
|
||||
|
||||
private static void LoginFail()
|
||||
{
|
||||
UICtrlDispatcher.Instance.Dispatch(UICtrlMsg.NetLoadingUI_Close);
|
||||
|
||||
void OnFail() {
|
||||
NetworkDispatcher.Instance.Dispatch(NetworkMsg.Login);
|
||||
}
|
||||
|
||||
UICtrlDispatcher.Instance.Dispatch(UICtrlMsg.TipsViewUI_Open, (Action) OnFail);
|
||||
}
|
||||
|
||||
public override void Dispose() {
|
||||
base.Dispose();
|
||||
RemoveListener();
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using IgnoreOPS;
|
||||
using SGModule.Common.Extensions;
|
||||
using SGModule.Common.Helper;
|
||||
using SGModule.NetKit;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BallKingdomCrush {
|
||||
public class LoginSystem : BaseSystem {
|
||||
private int loginCount = 0;
|
||||
|
||||
private bool _isLogin = false;
|
||||
|
||||
|
||||
private TimerTask timerTask = null;
|
||||
|
||||
public LoginSystem(bool isAutoInit = true) {
|
||||
if (isAutoInit) {
|
||||
Init();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed override void Init() {
|
||||
base.Init();
|
||||
InitData();
|
||||
AddListener();
|
||||
}
|
||||
|
||||
private void InitData() {
|
||||
}
|
||||
|
||||
private void AddListener() {
|
||||
NetworkDispatcher.Instance.AddListener(NetworkMsg.Login, RequestLogin);
|
||||
}
|
||||
|
||||
private void RemoveListener() {
|
||||
NetworkDispatcher.Instance.RemoveListener(NetworkMsg.Login, RequestLogin);
|
||||
}
|
||||
|
||||
private void RequestLogin(object obj = null) {
|
||||
|
||||
// if (!GameHelper.IsConnect())
|
||||
// {
|
||||
// LoginFail();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
if (_isLogin) return;
|
||||
_isLogin = true;
|
||||
|
||||
TrackKit.TrackLoginFunnel(LoginFunnelEventType.LoginSend);
|
||||
UICtrlDispatcher.Instance.Dispatch(UICtrlMsg.NetworkErrorTipsUI_Open);
|
||||
Log.Info("login request", $"attribution: {SuperApplication.Instance.attribution}, haveSimCard: {NetworkManager.haveSimCard}");
|
||||
LoginKit.Instance.LoginRequest(SuperApplication.Instance.attribution.ToLower(), NetworkManager.haveSimCard, (isSuccess, loginData) => {
|
||||
TrackKit.TrackLoginFunnel(LoginFunnelEventType.LoginRecv, isSuccess ? "success" : "fail");
|
||||
|
||||
UICtrlDispatcher.Instance.Dispatch(UICtrlMsg.NetworkErrorTipsUI_Close);
|
||||
|
||||
if (isSuccess)
|
||||
{
|
||||
Debug.Log($"loginData.CdnURL======={loginData.CdnURL}");
|
||||
// AB上传 BI
|
||||
BIManager.Instance.TrackABConfig(loginData.IsMagic ? 30 : 15);
|
||||
|
||||
// loginData.CdnURL = "https://asserts.minskyfun.top";
|
||||
|
||||
|
||||
// TextureHelper.imgUrl = loginData.CdnURL + "/encrypt/image/";
|
||||
// LiveVideoManager.videoBaseUrl = loginData.CdnURL + "/encrypt/video/";
|
||||
|
||||
DateTimeManager.Instance.SetServerCurrTimestamp(loginData.LoginTime);
|
||||
|
||||
NetworkDispatcher.Instance.Dispatch(NetworkMsg.GetPlayData);
|
||||
|
||||
MaxADKit.SetUserID(loginData.Uid.As<string>());
|
||||
}
|
||||
else
|
||||
{
|
||||
LoginFail();
|
||||
}
|
||||
});
|
||||
// }
|
||||
}
|
||||
|
||||
private static void LoginFail()
|
||||
{
|
||||
UICtrlDispatcher.Instance.Dispatch(UICtrlMsg.NetLoadingUI_Close);
|
||||
|
||||
void OnFail() {
|
||||
NetworkDispatcher.Instance.Dispatch(NetworkMsg.Login);
|
||||
}
|
||||
|
||||
UICtrlDispatcher.Instance.Dispatch(UICtrlMsg.TipsViewUI_Open, (Action) OnFail);
|
||||
}
|
||||
|
||||
public override void Dispose() {
|
||||
base.Dispose();
|
||||
RemoveListener();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user