using Gs2.Unity.Util; using System; using System.Threading.Tasks; using UnityEngine; using GS2Studio.Generated.Quest; using GS2Studio.Generated.Progress; using GS2Studio.Generated.Wallet; using GS2Studio.Generated.Energy; using GS2Studio.Generated.LoginRewardCollection; using GS2Studio.Generated.Mission; using GS2Studio.Generated.MissionCounter; public sealed class AdventureStudioView : MonoBehaviour { [SerializeField] private QuestListHandler quests; private bool busy; private string purchaseId; private bool unresolved; private string message = ""; [SerializeField] private ProgressHandler progress; [SerializeField] private WalletHandler wallet; [SerializeField] private EnergyHandler energy; [SerializeField] private LoginRewardCollectionHandler loginReward; [SerializeField] private MissionHandler mission; [SerializeField] private MissionCounterHandler counter; [SerializeField] private string missionGroup = "adventure"; [SerializeField] private string missionName = "clear3"; private void Awake() { loginReward.SetKeys("daily"); mission.SetKeys(missionName, missionGroup); mission.SetSdkKeys(missionGroup); counter.SetKeys("clear"); } private void OnEnable() { if (quests != null) quests.Failed += ShowLoadError; if (progress != null) progress.Failed += ShowLoadError; if (wallet != null) wallet.Failed += ShowLoadError; if (energy != null) energy.Failed += ShowLoadError; loginReward.Failed += ShowLoadError; mission.Failed += ShowLoadError; counter.Failed += ShowLoadError; } private void OnDisable() { if (quests != null) quests.Failed -= ShowLoadError; if (progress != null) progress.Failed -= ShowLoadError; if (wallet != null) wallet.Failed -= ShowLoadError; if (energy != null) energy.Failed -= ShowLoadError; loginReward.Failed -= ShowLoadError; mission.Failed -= ShowLoadError; counter.Failed -= ShowLoadError; } private void ShowLoadError(Exception error) { message = "Could not load: " + error.GetType().Name; } private void OnGUI() { var sessionHolder = Gs2GameSessionHolder.Instance; if (quests == null || sessionHolder == null || !sessionHolder.Initialized) { return; } GUILayout.BeginArea(new Rect(20, 100, 650, 650), GUI.skin.box); GUILayout.Label(message); if (quests.IsLoaded) { DrawQuestButtons(); DrawPlayerStatus(); DrawShop(); DrawDailyRewards(); } else { GUILayout.Label("Loading adventures..."); } GUI.enabled = true; GUILayout.EndArea(); } private void DrawQuestButtons() { var canOperate = !busy && !unresolved && progress.HasValue; GUI.enabled = canOperate && !progress.Model.InProgress; foreach (var quest in quests.Binders) { GUILayout.Label(quest.DisplayName); if (GUILayout.Button("Start: " + quest.DisplayName)) { Run(() => quest.Start()); } } GUI.enabled = canOperate && progress.Model.InProgress; if (GUILayout.Button("Complete")) { Run(() => progress.Binder.Complete()); } GUI.enabled = true; } private void DrawPlayerStatus() { GUILayout.Label(wallet.HasValue ? "Coins: " + wallet.Model.Free : "Loading coins..."); if (!progress.HasValue) { GUILayout.Label("Loading progress..."); } else { GUILayout.Label(progress.Model.InProgress ? "Adventure in progress" : "Choose an adventure"); } GUILayout.Label(energy.HasValue ? "Stamina: " + energy.Model.CurrentValue : "Loading stamina..."); } private void DrawShop() { GUI.enabled = !busy && (!unresolved || purchaseId != null); if (GUILayout.Button(purchaseId == null ? "Restore 10 stamina for 20 coins" : "Retry the same purchase")) { Run(Buy, retryPurchase: purchaseId != null); } GUI.enabled = true; } private void DrawDailyRewards() { GUILayout.Space(12); GUILayout.Label("Login rewards and missions"); if (!loginReward.HasValue || !mission.HasValue || !counter.HasValue) { GUILayout.Label("Loading reward details..."); return; } var steps = loginReward.Model.ReceivedSteps; for (var day = 0; day < 3; day++) { var received = steps != null && day < steps.Count && steps[day]; GUILayout.Label($"Day {day + 1}: {(day + 1) * 10} coins / " + (received ? "Claimed" : "Not claimed")); } GUI.enabled = !busy && !unresolved; if (GUILayout.Button("Claim today's login reward")) Run(() => loginReward.Binder.Receive()); GUILayout.Label($"Total adventures completed: {counter.Model.TotalValue}"); GUILayout.Label(mission.Model.Received ? "Claimed" : mission.Model.Completed ? "You can claim the 30-coin mission reward" : "Mission in progress"); GUI.enabled = !busy && !unresolved && mission.Model.Completed && !mission.Model.Received; if (GUILayout.Button("Claim 30-coin mission reward")) Run(() => mission.Binder.Receive()); GUI.enabled = true; } private async void Run(Func operation, bool retryPurchase = false) { if (busy || (unresolved && !retryPurchase)) return; busy = true; unresolved = true; message = "Processing..."; try { await operation(); unresolved = false; message = "Action completed"; } catch (Exception error) { if (error is Gs2.Gs2Stamina.Exception.InsufficientException || error is Gs2.Gs2Money2.Exception.InsufficientException) { unresolved = false; purchaseId = null; message = error is Gs2.Gs2Stamina.Exception.InsufficientException ? "Not enough stamina. Recover stamina and try again." : "Not enough coins. Earn more in adventures and try again."; } else if (error is Gs2.Core.Exception.BadRequestException) { unresolved = false; purchaseId = null; message = "Action failed: " + error.Message; } else message = purchaseId != null ? "Check the connection and retry the same purchase: " + error.GetType().Name : "Cannot confirm the result. New actions are paused: " + error.GetType().Name; } finally { busy = false; } } private async Task Buy() { purchaseId ??= Guid.NewGuid().ToString(); var request = Gs2ClientHolder.Instance.Gs2.Exchange.Namespace("EnergyProduct") .Me(Gs2GameSessionHolder.Instance.GameSession).Exchange(); var transaction = await request.ExchangeAsync( "refill", 1, speculativeExecute: false, duplicationAvoider: purchaseId); if (transaction != null) await transaction.WaitAsync(all: true); purchaseId = null; } }