using System; using System.Threading; using System.Threading.Tasks; using asap.core; using UnityEngine; using UnityEngine.UI; using GameCore; using System.Linq; namespace game { public class PFLoginAct : AGameAct { [Inject] public IUserService userService { get; set; } [Inject] public IConfig config { get; set; } [Inject] public IInGameMailService MailService { get; set; } [Inject] public IRTService rtService { get; set; } [Inject] public IIAPService iapService { get; set; } private PlayerDataStorage.IKVUserLifecycle kvLifecycle => userService as PlayerDataStorage.IKVUserLifecycle; [SerializeField] private GameObject customInput; [SerializeField] private InputField customIdInput; [SerializeField] private Button inputOkBtn; [SerializeField] SimpleDialog dialog; private string[] loadingInfos; private CancellationTokenSource loginLifetime; private CancellationToken loginToken; public override async Task StartAsync() { loginLifetime = CancellationTokenSource.CreateLinkedTokenSource(userService.LoginLifetime); loginToken = loginLifetime.Token; Debug.Log("PFLoginAct StartAsync"); loadingInfos = new string[] { "UI_FishingLoginPanel_LoginGameStage_1", "UI_FishingLoginPanel_LoginGameStage_2", "UI_FishingLoginPanel_LoginGameStage_3", "UI_FishingLoginPanel_LoginGameStage_4", "UI_FishingLoginPanel_LoginGameStage_5", "UI_FishingLoginPanel_LoginGameStage_6", "UI_FishingLoginPanel_LoginGameStage_7", "UI_FishingLoginPanel_LoginGameStage_8", "UI_FishingLoginPanel_LoginGameStage_9" }.Select(key => LocalizationMgr.GetText(key)).ToArray(); await base.StartAsync(); if (loginToken.IsCancellationRequested) return false; DoLogin(); return true; } //CancellationTokenSource source; private async void DoLogin() { try { await LoginAsync(); } catch (OperationCanceledException) when (loginToken.IsCancellationRequested) { } catch (Exception ex) { Debug.LogException(ex); } finally { StopLoadingInfo(); } } private async Task LoginAsync() { loginToken.ThrowIfCancellationRequested(); UpdateLoadingInfo(); var configCustomId = config.Get("CustomID", string.Empty); #if UNITY_EDITOR && !SERVICE_HOST if(game.PlayerDataStorage.PlayerKVGameplayLoop.Enabled) configCustomId=game.PlayerDataStorage.PlayerKVGameplayLoop.Permit.PlayerId; #endif if (configCustomId == @"{{input}}") { LoadingScreen.HideProgressBar(); StopLoadingInfo(); await InputID(); loginToken.ThrowIfCancellationRequested(); LoadingScreen.ShowProgressBar(); UpdateLoadingInfo(); } else { userService.CustomId = configCustomId; } //source = new CancellationTokenSource(); //LoadingAutoInc(source.Token, 1f); var formalKV=SubBoostrap.RuntimeSelection?.IsKV==true; rtService.WaitForAPISvrLogin(); var step = await userService.Login(OnLoginStep); loginToken.ThrowIfCancellationRequested(); if(formalKV) { StopLoadingInfo(); LoadingScreen.HideProgressBar(); if(step==ELoginStep.Done && kvLifecycle?.KVHandoffReady==true) LoadingScreen.SetLoadingInfo("KV account loaded. Gameplay is not enabled yet."); else { var error=kvLifecycle?.KVLastError.ToString() ?? "Input"; dialog.Config(new SimpleDialog.Context { message="KV login unavailable", message2="Login stopped ("+error+"). Sign out or restart before trying again.", okAction=()=>userService.Logout(), closeAction=()=>userService.Logout() }); } return; } if (step != ELoginStep.Done) { #if UNITY_EDITOR && !SERVICE_HOST if(game.PlayerDataStorage.PlayerKVGameplayLoop.Enabled) throw game.PlayerDataStorage.PlayerKVGameplayLoop.Stop("Login failed; restart the Unity process before another attempt."); #endif //source.Cancel(); //source.Dispose(); await ReytryDialog(userService.Login, LocalizationMgr.GetText("subtitle_loginfailed") , LocalizationMgr.GetText("msg_loginfailed")); } loginToken.ThrowIfCancellationRequested(); StopLoadingInfo(); //source.Cancel(); //source.Dispose(); // try // { // await rtService.Connect(); // } // catch (Exception ex) // { // Debug.LogException(ex); // } MailService.Init(); iapService.Init(); Unload(); } private async Task InputID() { customInput.SetActive(true); var tempInput = PlayerPrefs.GetString("CustomID", string.Empty); var inputTask = new TaskCompletionSource(); UnityEngine.Events.UnityAction accept = () => { if (!loginToken.IsCancellationRequested) inputTask.TrySetResult(customIdInput.text); }; inputOkBtn.onClick.AddListener(accept); customIdInput.text = tempInput; try { using (loginToken.Register(() => inputTask.TrySetCanceled())) tempInput = await inputTask.Task; } finally { if (inputOkBtn != null) inputOkBtn.onClick.RemoveListener(accept); } loginToken.ThrowIfCancellationRequested(); if (!string.IsNullOrEmpty(tempInput)) { PlayerPrefs.SetString("CustomID", tempInput); } userService.CustomId = tempInput; customInput.SetActive(false); } private async Task ReytryDialog(Func, bool, Task> func, string title, string message) { while (true) { loginToken.ThrowIfCancellationRequested(); //source = new CancellationTokenSource(); var retry = new TaskCompletionSource(); bool submitted = false; async void Submit() { if (submitted || loginToken.IsCancellationRequested) return; submitted = true; try { if (config.Get("CustomID", string.Empty) == @"{{input}}") { LoadingScreen.HideProgressBar(); StopLoadingInfo(); await InputID(); loginToken.ThrowIfCancellationRequested(); LoadingScreen.ShowProgressBar(); UpdateLoadingInfo(); } retry.TrySetResult(await func(OnLoginStep, true)); } catch (Exception ex) { retry.TrySetException(ex); } } using var cancellation = loginToken.Register(() => retry.TrySetCanceled()); //LoadingAutoInc(source.Token, 1f); dialog.Config(new SimpleDialog.Context() { message = title, message2 = message, okAction = Submit, closeAction = Submit }); var result = await retry.Task; //LoadingAutoInc(source.Token, 1f); await Task.Delay(1000, loginToken); if (result == ELoginStep.Done) return; //else //{ //source.Cancel(); //source.Dispose(); //} } } private void OnLoginStep(int step) { if (loginToken.IsCancellationRequested) return; LoadingScreen.SetProgress(0.2f + step / 2.0f * 0.3f); } float lastChangeTime = 0; float lastWaitTime = 0; int lastChangeIndex = 0; float Text_Change_interval = 1.5f; float Text_Wait_Interval = 0.15f; bool isUpdatingLoadingInfo; private async void UpdateLoadingInfo() { if (isUpdatingLoadingInfo) return; isUpdatingLoadingInfo = true; var deltaTime = 0f; var info = string.Empty; while (isUpdatingLoadingInfo && !loginToken.IsCancellationRequested) { info = GetTextByDeltaTime(deltaTime, info); LoadingScreen.SetLoadingInfo(info); await Awaiters.NextFrame; deltaTime += Time.deltaTime; } } private string GetTextByDeltaTime(float deltaTime, string txt) { if (deltaTime == 0) { lastChangeTime = 0; lastChangeIndex = 0; return loadingInfos[0]; } var interval = deltaTime - lastChangeTime; if (interval > Text_Change_interval) { lastWaitTime = deltaTime; lastChangeTime = deltaTime; lastChangeIndex++; return loadingInfos[lastChangeIndex % loadingInfos.Length]; } return txt; } //private string GetTextByDeltaTime(float deltaTime, string txt) //{ //if (deltaTime == 0) //{ //lastChangeTime = 0; //lastChangeIndex = 0; //return loadingInfos[0]; //} //var interval = deltaTime - lastChangeTime; //if (interval > Text_Change_interval) //{ //lastWaitTime = deltaTime; //lastChangeTime = deltaTime; //lastChangeIndex++; //return loadingInfos[lastChangeIndex % loadingInfos.Length]; //} //interval = deltaTime - lastWaitTime; //if (interval > Text_Wait_Interval) //{ //var info = loadingInfos[lastChangeIndex % loadingInfos.Length]; //lastWaitTime = deltaTime; //if(txt.Length - info.Length >= 4) //return info; //return txt + "."; //} //return txt; //} private void StopLoadingInfo() { isUpdatingLoadingInfo = false; } protected override void OnDestroy() { StopLoadingInfo(); loginLifetime?.Cancel(); loginLifetime?.Dispose(); loginLifetime = null; if(SubBoostrap.RuntimeSelection?.IsKV==true) userService.Logout(); } //protected async void LoadingAutoInc(CancellationToken token, float total) //{ //float progress = 0.01f; //string msg = LocalizationMgr.GetRandomText(); //LoadingScreen.ShowProgressBar(); //LoadingScreen.SetProgress(progress); //LoadingScreen.SetLoadingInfo(msg); //string msg_mem = msg; //try //{ //float timer=0; //float innertimer=0; //float innerTimer2 = 0; //while(progress < 1) //{ //timer+=(Time.deltaTime+0.1f); //innertimer+=(Time.deltaTime+0.1f); //innerTimer2+=(Time.deltaTime+0.1f); //if (token.IsCancellationRequested) //break; ////每0.3秒给原信息后加一个. //if(innertimer>0.3f){ //msg = ""+msg+"."; //LoadingScreen.SetLoadingInfo(msg); //innertimer=0; //} //if(innerTimer2>1.2f){ //msg=msg_mem; //LoadingScreen.SetLoadingInfo(msg); //innerTimer2=0; //innertimer=0; //} //if(timer>2.4f){ //msg = LocalizationMgr.GetRandomText(); //msg_mem = msg; //LoadingScreen.SetLoadingInfo(msg); //timer=0; //innertimer = 0; //innerTimer2 = 0; //} //progress = Mathf.Min(progress + 0.01f, total); //LoadingScreen.SetProgress(progress); //await Task.Delay(100); //} //} //catch (System.Exception) //{ //LoadingScreen.SetProgress(0); //LoadingScreen.HideProgressBar(); //LoadingScreen.SetLoadingInfo(string.Empty); //} //} } }