using System; using System.Collections.Generic; using System.Diagnostics; using CIG.Extensions; using SUISS.Core; using SUISSEngine; using UnityEngine; namespace CIG { [RequireComponent(typeof(Serializing))] public sealed class VideoAds1Manager : SingletonMonobehaviour { //[DebuggerBrowsable(DebuggerBrowsableState.Never)] public event VideoAds1Manager.AvailabilityChangedEventHandler AvailabilityChangedEvent; private void FireAvailabilityChangedEvent() { if (this.AvailabilityChangedEvent != null) { this.AvailabilityChangedEvent(); } } //[DebuggerBrowsable(DebuggerBrowsableState.Never)] public event VideoAds1Manager.UnlockedEventHandler UnlockedEvent; private void FireUnlockedEvent() { if (this.UnlockedEvent != null) { this.UnlockedEvent(); } } protected override void Awake() { base.Awake(); if (this._isValidNewInstance) { AdProviderType[] array = new AdProviderType[3]; array[0] = AdProviderType.Chartboost; array[1] = AdProviderType.Vungle; this._adWaterfall = new AdWaterfall(array); } } protected override void OnDestroy() { if (SingletonMonobehaviour.IsAvailable) { SingletonMonobehaviour.Instance.PullRequestCompleted -= this.OnPullRequestCompleted; } if (SingletonMonobehaviour.IsAvailable) { SingletonMonobehaviour.Instance.AdAvailabilityChangedEvent -= this.OnAdAvailabilityChangedEvent; } this.CancelInvoke(new Action(this.OnValidateVideoAvailability)); base.OnDestroy(); } public bool ShowVideoQuestAd() { return this.ShowAd(delegate(bool success, bool clicked) { if (success) { SingletonMonobehaviour.Instance.AddNumberOfGoldVideosWatched(1); } }); } public bool ShowAd(Action callback) { return this.IsReady && this._adWaterfall.ShowAd(delegate(bool success, bool clicked) { this.OnVideoWatched(success, clicked, callback); }); } public bool IsReady { get { return this._adWaterfall != null && this._pullRequestCompleted && Mathf.Approximately(this.RemainingSecondsUntilNextVideo, 0f) && this._adWaterfall.IsReady; } } public float RemainingUnlockSeconds { get { return Mathf.Max(0f, (float)this._unlockTime.Subtract(DateTime.UtcNow).TotalSeconds); } } public bool IsUnlocked { get { return Mathf.Approximately(this.RemainingUnlockSeconds, 0f); } } public bool IsAvailableOnPlatform { get { return this._adWaterfall != null; } } private void OnSerialize(Dictionary dict) { StorageDictionary storageDictionary = new StorageDictionary(dict); storageDictionary.Set("UnlockStartTime", this._unlockStartTime); storageDictionary.Set("UnlockSeconds", this._unlockSeconds); storageDictionary.Set("WatchedVideoTimestamps", this._watchedVideoTimestamps); } private void OnDeserialize(Dictionary dict) { StorageDictionary storageDictionary = new StorageDictionary(dict); this._unlockStartTime = storageDictionary.GetDateTime("UnlockStartTime", DateTime.UtcNow); this._unlockSeconds = storageDictionary.Get("UnlockSeconds", 300); this._watchedVideoTimestamps = storageDictionary.GetDateTimeList("WatchedVideoTimestamps"); } private void OnDeserialized() { if (this._watchedVideoTimestamps == null) { this._unlockStartTime = DateTime.UtcNow; this._unlockSeconds = 300; this._watchedVideoTimestamps = new List(); this._unlockTime = this._unlockStartTime.AddSeconds((double)this._unlockSeconds); this._serializing.Serialize(); } CIGWebService instance = SingletonMonobehaviour.Instance; instance.PullRequestCompleted += this.OnPullRequestCompleted; if (instance.HasPulled) { this.OnPullRequestCompleted(); } SingletonMonobehaviour.Instance.AdAvailabilityChangedEvent += this.OnAdAvailabilityChangedEvent; } private void OnPullRequestCompleted() { bool isReady = this.IsReady; Dictionary properties = SingletonMonobehaviour.Instance.Properties; this._unlockSeconds = properties.GetInt("video_rewards_unlock_seconds", 300); this._videoTimeoutSeconds = (double)properties.GetInt("video_rewards_timeout_seconds", 14400); this._watchedVideoTimespan = new TimeSpan(properties.GetInt("video_rewards_timespan_hours", 24), 0, 0); this._maxWatchedVideosPerTimespan = properties.GetInt("video_rewards_max", 3); this._unlockTime = this._unlockStartTime.AddSeconds((double)this._unlockSeconds); this._pullRequestCompleted = true; bool isReady2 = this.IsReady; this.CancelInvoke(new Action(this.OnValidateVideoAvailability)); this.CancelInvoke(new Action(this.FireUnlockedEvent)); if (isReady != isReady2) { this.FireAvailabilityChangedEvent(); } if (!isReady2) { float time = Mathf.Max(this.RemainingSecondsUntilNextVideo, 30f); this.Invoke(new Action(this.OnValidateVideoAvailability), time, false); } if (!this.IsUnlocked) { this.Invoke(new Action(this.OnValidateUnlockedState), Mathf.Max(0f, this.RemainingUnlockSeconds), false); } } private void OnVideoWatched(bool success, bool clicked, Action callback) { this.PruneWatchedVideoTimestamps(false); this._watchedVideoTimestamps.Add(DateTime.UtcNow); this._serializing.Serialize(); this.CancelInvoke(new Action(this.OnValidateVideoAvailability)); this.Invoke(new Action(this.OnValidateVideoAvailability), this.RemainingSecondsUntilNextVideo, false); if (callback != null) { callback(success, clicked); } } private void OnValidateUnlockedState() { if (this.IsUnlocked) { this.FireUnlockedEvent(); } else { this.Invoke(new Action(this.OnValidateUnlockedState), Mathf.Max(0f, this.RemainingUnlockSeconds), false); } } private void OnValidateVideoAvailability() { this.PruneWatchedVideoTimestamps(true); if (this.IsReady) { this.FireAvailabilityChangedEvent(); } else { float time = Mathf.Max(this.RemainingSecondsUntilNextVideo, 30f); this.Invoke(new Action(this.OnValidateVideoAvailability), time, false); } } private void OnAdAvailabilityChangedEvent(AdProviderType providerType) { if (this._adWaterfall.ContainsAdProvider(providerType)) { this.FireAvailabilityChangedEvent(); } } private void PruneWatchedVideoTimestamps(bool serialize) { DateTime now = DateTime.UtcNow; int count = this._watchedVideoTimestamps.Count; this._watchedVideoTimestamps.RemoveAll((DateTime x) => now.Subtract(x) >= this._watchedVideoTimespan); if (serialize && this._watchedVideoTimestamps.Count != count) { this._serializing.Serialize(); } } private double RemainingVideoTimeoutSeconds { get { int count = this._watchedVideoTimestamps.Count; if (count <= 0) { return 0.0; } return this._videoTimeoutSeconds - DateTime.UtcNow.Subtract(this._watchedVideoTimestamps[count - 1]).TotalSeconds; } } private double RemainingVideoTimespanTimeoutSeconds { get { if (this._maxWatchedVideosPerTimespan == 0) { return double.MaxValue; } int count = this._watchedVideoTimestamps.Count; if (count < this._maxWatchedVideosPerTimespan || count == 0) { return 0.0; } return this._watchedVideoTimespan.TotalSeconds - DateTime.UtcNow.Subtract(this._watchedVideoTimestamps[0]).TotalSeconds; } } private float RemainingSecondsUntilNextVideo { get { if (!this._pullRequestCompleted) { return float.MaxValue; } return Mathf.Max(new float[] { 0f, this.RemainingUnlockSeconds, (float)this.RemainingVideoTimeoutSeconds, (float)this.RemainingVideoTimespanTimeoutSeconds }); } } private const string UnlockSecondsServerKey = "video_rewards_unlock_seconds"; private const string TimeoutSecondsServerKey = "video_rewards_timeout_seconds"; private const string TimespanHoursServerKey = "video_rewards_timespan_hours"; private const string TimespanMaxVideosServerKey = "video_rewards_max"; private const string UnlockStartTimeKey = "UnlockStartTime"; private const string UnlockSecondsKey = "UnlockSeconds"; private const string WatchedVideoTimestampsKey = "WatchedVideoTimestamps"; private const float ProviderAvailabilityValidationDelayInSeconds = 30f; private const int DefaultUnlockSeconds = 300; [SerializeField] private Serializing _serializing; private int _unlockSeconds; private double _videoTimeoutSeconds; private TimeSpan _watchedVideoTimespan; private int _maxWatchedVideosPerTimespan; private DateTime _unlockStartTime; private List _watchedVideoTimestamps; private bool _pullRequestCompleted; private AdWaterfall _adWaterfall; private DateTime _unlockTime; public delegate void AvailabilityChangedEventHandler(); public delegate void UnlockedEventHandler(); } }