Playvoi/Assets/ShiroginSDK/Runtime/Modules/Data/Scripts/RemoteConfigData.cs

203 lines
No EOL
8.7 KiB
C#

using System;
using System.Globalization;
using System.Linq;
using ShiroginSDK.Runtime.Services.Base;
using ShiroginSDK.Runtime.Services.Interfaces;
using UnityEngine;
namespace ShiroginSDK.Runtime.Modules.Data.Scripts
{
/// <summary>
/// Unified Remote Config system that merges local BaseData cache
/// and remote Firebase values.
/// </summary>
[Serializable]
public class RemoteConfigData : BaseData
{
// ---------------------------
// 🔹 Gameplay & Ads Settings
// ---------------------------
public int InterstitialTime = 180;
public int RewardedAfterInterstitialTime = 50;
public int FirstGameInterstitialTime = 120;
public int HpScale = 100;
public int DamageScale = 100;
public int ReviveCount = 1;
public int ReviveTime = 8;
public int RewardedAdSkipTime = 1;
public int RewardedSkillOfferCD = 45;
public string GameName = "default_game_name";
public string IOSRemoveAds = "dihe_noads";
public string AndroidRemoveAds = "dihe_noads";
public bool RemoveAdsPopupActive = true;
public int RemoveAdsPopupFrequency = 10;
public int PassiveUpgradeBasePrice = 10;
public int RateUsShowGameCount = 2;
public int TargetFps = 60;
public float[] EnemyHpMultiplier = { 1, 1.4f, 2, 2.5f, 3, 3.5f, 4, 4.5f, 5, 6 };
public float[] EnemyDamageMultiplier = { 1, 1.4f, 2, 2, 2.5f, 3, 3, 3.5f, 4, 4 };
public float ExpMultiplier = 1f;
public float GoldMultiplier = 1f;
public float[] BossHpMultiplier = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
public float[] BossDamageMultiplier = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
public int ForceOpenStoreStartGameCount = 2;
public int ForceOpenStoreFrequency = 3;
public string StoreData = "{}"; // 🔹 CharacterStoreData + IAPStoreData birleşti
public bool InterTimeUnscale;
public float PauseSceneInterTime = 15000;
public bool ShuffleActive = true;
public bool IAPStoreActive = true;
public int TicketPopupShowRewardedCount = 999999;
// 🔹 Firebase RemoteConfig cache metadata
public string CachedJson = "{}";
public long LastFetchTicksUtc;
protected override string PrefsKey => "REMOTE_CONFIG_DATA";
/// <summary>
/// Checks whether we should fetch new Firebase data (older than 24h or empty)
/// </summary>
public bool ShouldFetchNewData()
{
if (string.IsNullOrEmpty(CachedJson) || CachedJson == "{}")
return true;
if (LastFetchTicksUtc <= 0)
return true;
var lastFetch = new DateTime(LastFetchTicksUtc, DateTimeKind.Utc);
var diff = DateTime.UtcNow - lastFetch;
return diff.TotalHours >= 24;
}
public void UpdateCache(string newJson)
{
if (string.IsNullOrEmpty(newJson))
newJson = "{}";
CachedJson = newJson;
LastFetchTicksUtc = DateTime.UtcNow.Ticks;
Save();
}
public string GetLastFetchTimeString()
{
if (LastFetchTicksUtc <= 0)
return "Never";
var dt = new DateTime(LastFetchTicksUtc, DateTimeKind.Utc);
return dt.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss");
}
/// <summary>
/// Loads local data, applies remote overrides, and saves updated values.
/// </summary>
public void Initialize()
{
Load(); // 🔹 Load local cache first
var remoteService = ServiceLocator.Get<IRemoteConfigService>();
if (remoteService == null)
{
Debug.LogWarning("[RemoteConfigData] ⚠️ IRemoteConfigService not initialized. Using local values.");
return;
}
// Merge logic: local fallback, remote override
InterstitialTime = GetIntMerged(remoteService, "interstitial_time", InterstitialTime);
RewardedAfterInterstitialTime = GetIntMerged(remoteService, "rewarded_after_interstitial_time",
RewardedAfterInterstitialTime);
FirstGameInterstitialTime =
GetIntMerged(remoteService, "first_game_interstitial_time", FirstGameInterstitialTime);
HpScale = GetIntMerged(remoteService, "hp_scale", HpScale);
DamageScale = GetIntMerged(remoteService, "damage_scale", DamageScale);
ReviveCount = GetIntMerged(remoteService, "revive_count", ReviveCount);
ReviveTime = GetIntMerged(remoteService, "revive_time", ReviveTime);
RewardedAdSkipTime = GetIntMerged(remoteService, "rewarded_ad_skip_time", RewardedAdSkipTime);
RewardedSkillOfferCD = GetIntMerged(remoteService, "rewarded_skill_offer_cd", RewardedSkillOfferCD);
RemoveAdsPopupFrequency =
GetIntMerged(remoteService, "remove_ads_popup_frequency", RemoveAdsPopupFrequency);
PassiveUpgradeBasePrice =
GetIntMerged(remoteService, "passive_upgrade_base_price", PassiveUpgradeBasePrice);
RateUsShowGameCount = GetIntMerged(remoteService, "rate_us_show_game_count", RateUsShowGameCount);
TargetFps = GetIntMerged(remoteService, "target_fps", TargetFps);
ForceOpenStoreStartGameCount = GetIntMerged(remoteService, "force_open_store_start_count",
ForceOpenStoreStartGameCount);
ForceOpenStoreFrequency =
GetIntMerged(remoteService, "force_open_store_frequency", ForceOpenStoreFrequency);
TicketPopupShowRewardedCount = GetIntMerged(remoteService, "ticket_popup_show_rewarded_count",
TicketPopupShowRewardedCount);
RemoveAdsPopupActive = GetBoolMerged(remoteService, "remove_ads_popup_active", RemoveAdsPopupActive);
InterTimeUnscale = GetBoolMerged(remoteService, "inter_unscale_time", InterTimeUnscale);
ShuffleActive = GetBoolMerged(remoteService, "shuffle_active", ShuffleActive);
IAPStoreActive = GetBoolMerged(remoteService, "iap_store_active", IAPStoreActive);
ExpMultiplier = GetFloatMerged(remoteService, "exp_multiplier", ExpMultiplier);
GoldMultiplier = GetFloatMerged(remoteService, "gold_multiplier", GoldMultiplier);
PauseSceneInterTime = GetFloatMerged(remoteService, "pause_scene_inter_time", PauseSceneInterTime);
GameName = GetStringMerged(remoteService, "game_name", GameName);
IOSRemoveAds = GetStringMerged(remoteService, "ios_remove_ads", IOSRemoveAds);
AndroidRemoveAds = GetStringMerged(remoteService, "android_remove_ads", AndroidRemoveAds);
StoreData = GetStringMerged(remoteService, "store_data", StoreData);
// Array parse
var ci = (CultureInfo)CultureInfo.InvariantCulture.Clone();
EnemyHpMultiplier = ParseArrayMerged(remoteService, "enemy_hp_multiplier", EnemyHpMultiplier, ci);
EnemyDamageMultiplier =
ParseArrayMerged(remoteService, "enemy_damage_multiplier", EnemyDamageMultiplier, ci);
BossHpMultiplier = ParseArrayMerged(remoteService, "boss_hp_multiplier", BossHpMultiplier, ci);
BossDamageMultiplier = ParseArrayMerged(remoteService, "boss_damage_multiplier", BossDamageMultiplier, ci);
Save();
Debug.Log("[RemoteConfigData] ✅ Remote + Local merge completed successfully.");
}
// -----------------------
// 🔧 Merge Helper Methods
// -----------------------
private int GetIntMerged(IRemoteConfigService r, string key, int localVal)
{
return r.GetInt(key, localVal);
}
private float GetFloatMerged(IRemoteConfigService r, string key, float localVal)
{
return r.GetFloat(key, localVal);
}
private bool GetBoolMerged(IRemoteConfigService r, string key, bool localVal)
{
return r.GetBool(key, localVal);
}
private string GetStringMerged(IRemoteConfigService r, string key, string localVal)
{
var remote = r.GetString(key, localVal);
return string.IsNullOrEmpty(remote) ? localVal : remote;
}
private float[] ParseArrayMerged(IRemoteConfigService r, string key, float[] localArray, CultureInfo ci)
{
var val = r.GetString(key, string.Join(",", localArray.Select(x => x.ToString(ci))));
try
{
return val.Split(',').Select(x => float.Parse(x, ci)).ToArray();
}
catch
{
return localArray;
}
}
}
}