RandomGFGoStop/Assets/Scripts/SingletonManagers/Managers/AccountManager.cs

873 lines
27 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading.Tasks;
using Firebase;
using Firebase.Auth;
using Google;
using System;
using UnityEngine.Events;
using System.Text;
using Newtonsoft.Json;
using Firebase.Database;
using Firebase.Crashlytics;
using Firebase.Extensions;
public class AccountManager : MonoBehaviour
{
[System.Serializable]
public class UploadData
{
public string Email;
public int Level;
public int UnlockDataCount;
public long Gold;
public long Heart;
public long Key;
public long BuyKeyCount;
public bool IsRemoveADS;
public int FreeHeartCount, FreeKeyCount;
public long BuyShopAccumulatedMoney;
}
private string webClientId = "502279241127-qvp2rjlutn9kqkpkjnr75uedi5hfu2dj.apps.googleusercontent.com";
[SerializeField]
private float networkTimeout = 10.0f;
[HideInInspector]
public UnityEvent<bool> OnAccountSignIn;
[HideInInspector]
public UnityEvent<bool> OnAccountSignOut;
[HideInInspector]
public UnityEvent<bool> OnUploadSaveData;
[HideInInspector]
public UnityEvent<bool> OnDownloadSaveData;
[HideInInspector]
public UnityEvent OnOverWriteSaveData;
private FirebaseAuth auth = null;
private FirebaseUser user = null;
private GoogleSignInConfiguration configuration;
private bool isLoginFail = false;
public bool IsLoginFail
{
get { return isLoginFail; }
}
public bool IsUserLogin
{
get { return user != null; }
}
private Coroutine checkExistSaveDataCoroutine;
private Coroutine uploadCoroutine;
private Coroutine downloadCoroutine;
private UploadData uploadData = new UploadData();
StringBuilder sb = new StringBuilder();
private GoogleSignInUser signInUser = new GoogleSignInUser();
private AuthResult signInUser_Email;
private bool IsTest = false;
private void Awake()
{
configuration = new GoogleSignInConfiguration { WebClientId = webClientId, RequestIdToken = true, RequestEmail = true };
//Firebase.Analytics.FirebaseAnalytics.SetAnalyticsCollectionEnabled(false);
//Crashlytics.ReportUncaughtExceptionsAsFatal = false;
Firebase.FirebaseApp.LogLevel = Firebase.LogLevel.Debug;
Firebase.Analytics.FirebaseAnalytics.SetAnalyticsCollectionEnabled(true);
Crashlytics.ReportUncaughtExceptionsAsFatal = true;
Firebase.Analytics.FirebaseAnalytics.SetUserProperty(
Firebase.Analytics.FirebaseAnalytics.UserPropertySignUpMethod,
"Google");
AutoSignIn();
}
void OnDestroy()
{
auth.StateChanged -= AuthStateChanged;
auth = null;
}
public void SignOut()
{
if (IsTest)
{
OnSignOut_Email();
}
else
{
OnSignOut();
}
}
private void SignOutFromGoogle() { OnSignOut(); }
private void SignOutFromEmail() { OnSignOut_Email(); }
public bool IsHaveLoginInfo()
{
return user != null ? user.IsValid() : false;
}
public void AutoSignIn()
{
StartCoroutine(StartAutoSignIn());
}
// checkExistSaveData == 서버에 세이브가 존재하는 지를 확인한다.
public void SignInWithUploadSaveData(bool checkExistSaveData)
{
if (IsTest)
{
StartCoroutine(StartSignInWithUploadSaveData_Email(checkExistSaveData));
}
else
{
StartCoroutine(StartSignInWithUploadSaveData(checkExistSaveData));
}
}
public void SignInWithDownloadSaveData()
{
if (IsTest)
{
StartCoroutine(StartSignInWithDownloadSaveData_Email());
}
else
{
StartCoroutine(StartSignInWithDownloadSaveData());
}
}
public string GetUserEmail()
{
if(user != null)
{
return user.Email;
}
return String.Empty;
}
public string GetUserID()
{
if (user != null)
{
return user.UserId;
}
return String.Empty;
}
private IEnumerator StartAutoSignIn()
{
Debug.Log("AccountManager: StartSignIn");
if (auth == null)
{
Task<DependencyStatus> task = InitializeFirebase();
if (task.IsCompleted == false)
{
yield return new WaitUntil(() => task.IsCompleted);
}
if (task.Result != DependencyStatus.Available)
{
yield break;
}
yield return StartCoroutine(ReloadUserData());
}
if (user != null)
{
if(IsTest)
{
OnSignIn_Email();
}
else
{
OnSignIn();
}
}
else
{
Debug.LogError("AccountManager: StartSignIn: user is null");
OnAccountSignIn?.Invoke(false);
}
}
private Task<DependencyStatus> InitializeFirebase()
{
Debug.Log("AccountManager: InitializeFirebase");
// CheckAndFixDependenciesAsync() == 구글 플레이 서비스 버전 요구사항 확인할 때 사용하는 함수
Task<DependencyStatus> tsak = FirebaseApp.CheckAndFixDependenciesAsync();
tsak.ContinueWithOnMainThread(task =>
{
sb.Clear();
if (task.IsCompleted)
{
if (task.Result == DependencyStatus.Available)
{
auth = FirebaseAuth.DefaultInstance;
auth.StateChanged += AuthStateChanged;
AuthStateChanged(this, null);
}
else
{
isLoginFail = true;
sb.Append("AccountManager: Could not resolve all Firebase dependencies: ").Append(task.Result.ToString());
Debug.LogError(sb.ToString());
}
}
else
{
isLoginFail = true;
sb.Append("AccountManager: Dependency check was not completed. Error : ").Append(task.Result.ToString());
Debug.LogError(sb.ToString());
}
});
return tsak;
}
private void AuthStateChanged(object sender, System.EventArgs eventArgs)
{
Debug.Log("AccountManager: AuthStateChanged");
if (auth.CurrentUser != user)
{
bool signedIn = user != auth.CurrentUser && auth.CurrentUser != null;
if (!signedIn && user != null)
{
Debug.Log("AccountManager: AuthStateChanged: Signed out");
}
user = auth.CurrentUser;
if (signedIn)
{
Debug.Log("AccountManager: AuthStateChanged: Signed in");
}
}
}
private IEnumerator ReloadUserData()
{
Debug.Log("AccountManager: ReloadUserData");
yield return new WaitForEndOfFrame();
// 정보 다시 가져오기
if (user != null)
{
var reloadUserTask = user.ReloadAsync();
yield return new WaitUntil(predicate: () => reloadUserTask.IsCompleted);
}
}
private Task<GoogleSignInUser> OnSignIn()
{
Debug.Log("AccountManager: Calling SignIn");
GoogleSignIn.Configuration = configuration;
GoogleSignIn.Configuration.UseGameSignIn = false;
GoogleSignIn.Configuration.RequestIdToken = true;
GoogleSignIn.Configuration.RequestEmail = true;
Task<GoogleSignInUser> task = GoogleSignIn.DefaultInstance.SignIn();
if (task.IsCompleted == false)
{
task.ContinueWith(OnAuthenticationFinished);
}
else
{
OnAuthenticationFinished(task);
}
return task;
}
private Task<FirebaseUser> OnCredential(Credential credential)
{
Debug.Log("AccountManager: OnCredential");
Task<FirebaseUser> task = auth.SignInWithCredentialAsync(credential);
if (task.IsCompleted == false)
{
task.ContinueWith(OnCredentialFinished);
}
else
{
OnCredentialFinished(task);
}
return task;
}
private void OnSignOut()
{
Debug.Log("AccountManager: Calling SignOut");
GoogleSignIn.DefaultInstance.SignOut();
auth.SignOut();
Firebase.Analytics.FirebaseAnalytics.SetAnalyticsCollectionEnabled(false);
Crashlytics.ReportUncaughtExceptionsAsFatal = false;
isLoginFail = false;
user = null;
OnAccountSignOut?.Invoke(true);
}
internal void OnAuthenticationFinished(Task<GoogleSignInUser> task)
{
Debug.Log("AccountManager: OnAuthenticationFinished");
sb.Clear();
if (task.IsFaulted)
{
using (IEnumerator<Exception> enumerator = task.Exception.InnerExceptions.GetEnumerator())
{
if (enumerator.MoveNext())
{
GoogleSignIn.SignInException error = (GoogleSignIn.SignInException)enumerator.Current;
sb.Append("AccountManager: Got Error: ").Append(error.Status).Append(" ").Append(error.Message);
Debug.LogError(sb.ToString());
}
else
{
sb.Append("AccountManager: Got Unexpected Exception?!?").Append(task.Exception);
Debug.LogError(sb.ToString());
}
}
OnAccountSignIn?.Invoke(false);
isLoginFail = true;
}
else if (task.IsCanceled)
{
Debug.LogError("AccountManager: OnAuthenticationFinished: Canceled");
OnAccountSignIn?.Invoke(false);
isLoginFail = true;
}
}
internal void OnCredentialFinished(Task<FirebaseUser> task)
{
Debug.LogError("AccountManager: OnCredentialFinished");
sb.Clear();
if (task.IsCanceled)
{
Debug.LogError("AccountManager: OnCredentialFinished: Canceled");
OnAccountSignIn?.Invoke(false);
isLoginFail = true;
}
else if (task.IsFaulted)
{
using (IEnumerator<Exception> enumerator = task.Exception.InnerExceptions.GetEnumerator())
{
if (enumerator.MoveNext())
{
GoogleSignIn.SignInException error = (GoogleSignIn.SignInException)enumerator.Current;
sb.Append("AccountManager: Got Error: ").Append(error.Status).Append(" ").Append(error.Message);
Debug.LogError(sb.ToString());
}
else
{
sb.Append("AccountManager: Got Unexpected Exception?!?").Append(task.Exception);
Debug.LogError(sb.ToString());
}
}
OnAccountSignIn?.Invoke(false);
isLoginFail = true;
}
}
private System.Threading.Tasks.Task SignInWithGoogleOnFirebase(string idToken)
{
Debug.LogError("AccountManager: SignInWithGoogleOnFirebase");
Credential credential = GoogleAuthProvider.GetCredential(idToken, null);
return auth.SignInAndRetrieveDataWithCredentialAsync(credential).ContinueWith(task =>
{
AggregateException ex = task.Exception;
if (ex != null)
{
if (ex.InnerExceptions[0] is FirebaseException inner && (inner.ErrorCode != 0))
{
sb.Clear();
sb.Append("\nError code = ").Append(inner.ErrorCode).Append(" Message = ").Append(inner.Message);
Debug.LogError(sb.ToString());
}
OnAccountSignIn?.Invoke(false);
isLoginFail = true;
}
else
{
Debug.Log("AccountManager: Sign In Successful.");
user = task.Result.User;
OnAccountSignIn?.Invoke(true);
isLoginFail = false;
if (auth.CurrentUser != null)
{
Firebase.Analytics.FirebaseAnalytics.SetUserId(auth.CurrentUser.UserId);
}
}
});
}
private IEnumerator StartSignInWithUploadSaveData(bool checkExistSaveData)
{
if (user == null)
{
Task<GoogleSignInUser> signInTask = OnSignIn();
if (signInTask.IsCompleted == false)
{
yield return new WaitUntil(() => signInTask.IsCompleted);
}
if (signInTask.IsCompletedSuccessfully == true)
{
signInUser = signInTask.Result;
sb.Append("AccountManager: Welcome: ").Append(signInTask.Result.Email);
Debug.Log(sb.ToString());
/*Credential credential = GoogleAuthProvider.GetCredential(signInTask.Result.IdToken, null);
Task<FirebaseUser> credentialTask = OnCredential(credential);
if (credentialTask.IsCompleted == false)
{
yield return new WaitUntil(() => credentialTask.IsCompleted);
}
if (credentialTask.IsCompletedSuccessfully == true)
{
Debug.Log("AccountManager: Sign In Successful.");
user = credentialTask.Result;
OnAccountSignIn.Invoke(true);
isLoginFail = false;
Firebase.FirebaseApp.LogLevel = Firebase.LogLevel.Debug;
Firebase.Analytics.FirebaseAnalytics.SetAnalyticsCollectionEnabled(true);
Crashlytics.ReportUncaughtExceptionsAsFatal = true;
Firebase.Analytics.FirebaseAnalytics.SetUserProperty(
Firebase.Analytics.FirebaseAnalytics.UserPropertySignUpMethod,
"Google");
if (auth.CurrentUser != null)
{
Firebase.Analytics.FirebaseAnalytics.SetUserId(auth.CurrentUser.UserId);
}
}*/
System.Threading.Tasks.Task signInWithGoogleOnFirebaseTask = SignInWithGoogleOnFirebase(signInTask.Result.IdToken);
if (signInWithGoogleOnFirebaseTask.IsCompleted == false)
{
yield return new WaitUntil(() => signInWithGoogleOnFirebaseTask.IsCompleted);
}
}
}
if (checkExistSaveData)
{
checkExistSaveDataCoroutine = StartCoroutine(CheckExistSaveData());
}
else
{
uploadCoroutine = StartCoroutine(UploadSaveData());
}
}
private IEnumerator CheckExistSaveData()
{
DatabaseReference databaseReference = FirebaseDatabase.DefaultInstance.RootReference;
if (databaseReference != null)
{
databaseReference.Child("users").Child(user.UserId).GetValueAsync().ContinueWith(task =>
{
if (task.IsFaulted || task.IsCanceled)
{
Debug.Log("AccountManager: CheckExistSaveData: DownloadSaveData Not Vaild");
if (uploadCoroutine != null)
{
StopCoroutine(uploadCoroutine);
uploadCoroutine = null;
}
uploadCoroutine = StartCoroutine(UploadSaveData());
}
else
{
DataSnapshot dataSnapshot = task.Result;
var jsonFile = dataSnapshot.GetRawJsonValue();
UploadData downloadData = JsonConvert.DeserializeObject<UploadData>(jsonFile);
if (downloadData.UnlockDataCount > GameManager.DB.GetUnlockTargetIndex(true) ||
downloadData.Level > GameManager.DB.NormalGameLevel)
{
Debug.Log("AccountManager: CheckExistSaveData: OverWriteSave");
}
else
{
Debug.Log("AccountManager: CheckExistSaveData: DownloadSaveData Success");
if(uploadCoroutine != null)
{
StopCoroutine(uploadCoroutine);
uploadCoroutine = null;
}
uploadCoroutine = StartCoroutine(UploadSaveData());
}
}
if (checkExistSaveDataCoroutine != null)
{
StopCoroutine(checkExistSaveDataCoroutine);
checkExistSaveDataCoroutine = null;
}
});
yield return new WaitForSeconds(networkTimeout);
OnUploadSaveData?.Invoke(false);
}
}
private IEnumerator UploadSaveData()
{
DatabaseReference databaseReference = FirebaseDatabase.DefaultInstance.RootReference;
if (databaseReference != null && user != null)
{
uploadData.Email = user.Email;
uploadData.UnlockDataCount = GameManager.DB.GetUnlockTargetIndex(true);
uploadData.Gold = GameManager.DB.Gold;
uploadData.Heart = GameManager.DB.Heart;
uploadData.Key = GameManager.DB.Key;
uploadData.BuyKeyCount = GameManager.DB.BuyKeyCount;
uploadData.Level = GameManager.DB.NormalGameLevel;
uploadData.FreeHeartCount = GameManager.DB.FreeHeartCount;
uploadData.FreeKeyCount = GameManager.DB.FreeKeyCount;
uploadData.IsRemoveADS = GameManager.DB.IsRemoveADS;
uploadData.BuyShopAccumulatedMoney = GameManager.DB.BuyShopAccumulatedMoney;
string json = JsonConvert.SerializeObject(uploadData);
databaseReference.Child("users").Child(user.UserId).SetRawJsonValueAsync(json).ContinueWith(task =>
{
if (task.IsCanceled || task.IsFaulted)
{
Debug.LogError("AccountManager: UploadSaveData: UploadSaveData Fail");
AggregateException ex = task.Exception;
if (ex != null)
{
if (ex.InnerExceptions[0] is FirebaseException inner && (inner.ErrorCode != 0))
{
sb.Clear();
sb.Append("AccountManager: UploadSaveData: UploadSaveData Fail: ").Append(inner.ErrorCode).Append(" Message = ").Append(inner.Message);
Debug.LogError(sb.ToString());
}
}
OnUploadSaveData?.Invoke(false);
}
else
{
Debug.Log("AccountManager: UploadSaveData: UploadSaveData Success");
OnUploadSaveData?.Invoke(true);
}
if (uploadCoroutine != null)
{
StopCoroutine(uploadCoroutine);
uploadCoroutine = null;
}
});
yield return new WaitForSeconds(networkTimeout);
OnUploadSaveData?.Invoke(false);
}
}
private IEnumerator StartSignInWithDownloadSaveData()
{
#if UNITY_EDITOR
yield return null;
GameManager.DB.DonwloadUnlockDataCount(100);
GameManager.DB.DonwloadGoldData(4000);
GameManager.DB.DonwloadHeartData(6);
GameManager.DB.DonwloadKeyData(5);
GameManager.DB.DownloadLevel(2);
GameManager.DB.DownloadIsRemoveADS(true);
OnDownloadSaveData?.Invoke(true);
#else
if (user == null)
{
Task<GoogleSignInUser> signInTask = OnSignIn();
if (signInTask.IsCompleted == false)
{
yield return new WaitUntil(() => signInTask.IsCompleted);
}
if (signInTask.IsCompletedSuccessfully == true)
{
signInUser = signInTask.Result;
sb.Append("AccountManager: Welcome: ").Append(signInTask.Result.Email);
Debug.Log(sb.ToString());
Task signInWithGoogleOnFirebaseTask = SignInWithGoogleOnFirebase(signInTask.Result.IdToken);
if(signInWithGoogleOnFirebaseTask.IsCompleted == false)
{
yield return new WaitUntil(() => signInWithGoogleOnFirebaseTask.IsCompleted);
}
}
}
downloadCoroutine = StartCoroutine(DownloadSaveData());
#endif
}
private IEnumerator DownloadSaveData()
{
DatabaseReference databaseReference = FirebaseDatabase.DefaultInstance.RootReference;
if (databaseReference != null)
{
databaseReference.Child("users").Child(user.UserId).GetValueAsync().ContinueWith(task =>
{
if (task.IsCanceled || task.IsFaulted)
{
Debug.LogError("AccountManager: DownloadSaveData: DownloadSaveData Fail");
OnDownloadSaveData?.Invoke(false);
}
else
{
Debug.Log("AccountManager: DownloadSaveData: DownloadSaveData Success");
DataSnapshot dataSnapshot = task.Result;
var jsonFile = dataSnapshot.GetRawJsonValue();
UploadData downloadData = JsonConvert.DeserializeObject<UploadData>(jsonFile);
GameManager.DB.DonwloadUnlockDataCount(downloadData.UnlockDataCount);
GameManager.DB.DonwloadGoldData(downloadData.Gold);
GameManager.DB.DonwloadHeartData(downloadData.Heart);
GameManager.DB.DonwloadKeyData(downloadData.Key);
GameManager.DB.DonwloadBuyKeyCountData(downloadData.BuyKeyCount);
GameManager.DB.DownloadLevel(downloadData.Level);
GameManager.DB.DownloadIsRemoveADS(downloadData.IsRemoveADS);
GameManager.DB.DownloadBuyShopAccumulatedMoney(downloadData.BuyShopAccumulatedMoney);
OnDownloadSaveData?.Invoke(true);
}
if (downloadCoroutine != null)
{
StopCoroutine(downloadCoroutine);
downloadCoroutine = null;
}
});
yield return new WaitForSeconds(networkTimeout);
OnDownloadSaveData?.Invoke(false);
}
}
private Task<AuthResult> OnSignIn_Email()
{
Debug.Log("AccountManager: Calling SignIn");
Task<AuthResult> task = auth.SignInWithEmailAndPasswordAsync("class.redsun00@gmail.com", "class00");
if (task.IsCompleted == false)
{
task.ContinueWith(OnAuthenticationFinished_Email);
}
else
{
OnAuthenticationFinished_Email(task);
}
return task;
}
internal void OnAuthenticationFinished_Email(Task<AuthResult> task)
{
Debug.Log("AccountManager: OnAuthenticationFinished_Email");
sb.Clear();
if (task.IsCanceled)
{
Debug.LogError("AccountManager: OnAuthenticationFinished_Email: SignInWithEmailAndPasswordAsync was canceled.");
}
if (task.IsFaulted)
{
Debug.LogError("AccountManager: OnAuthenticationFinished_Email: SignInWithEmailAndPasswordAsync encountered an error: " + task.Exception);
}
else
{
return;
}
OnAccountSignIn?.Invoke(false);
isLoginFail = true;
}
private IEnumerator StartSignInWithUploadSaveData_Email(bool checkExistSaveData)
{
if (user == null)
{
Task<AuthResult> signInTask = OnSignIn_Email();
if (signInTask.IsCompleted == false)
{
yield return new WaitUntil(() => signInTask.IsCompleted);
}
if (signInTask.IsCompletedSuccessfully == true)
{
user = signInTask.Result.User;
OnAccountSignIn?.Invoke(true);
isLoginFail = false;
Debug.Log("AccountManager: Sign In Successful.");
sb.Append("AccountManager: Welcome: ").Append(signInTask.Result.User.Email);
Debug.Log(sb.ToString());
Firebase.FirebaseApp.LogLevel = Firebase.LogLevel.Debug;
Firebase.Analytics.FirebaseAnalytics.SetAnalyticsCollectionEnabled(true);
Crashlytics.ReportUncaughtExceptionsAsFatal = true;
Firebase.Analytics.FirebaseAnalytics.SetUserProperty(
Firebase.Analytics.FirebaseAnalytics.UserPropertySignUpMethod,
"Google");
if (auth.CurrentUser != null)
{
Firebase.Analytics.FirebaseAnalytics.SetUserId(auth.CurrentUser.UserId);
}
}
else
{
yield break;
}
}
if (checkExistSaveData)
{
checkExistSaveDataCoroutine = StartCoroutine(CheckExistSaveData());
}
else
{
uploadCoroutine = StartCoroutine(UploadSaveData());
}
}
private IEnumerator StartSignInWithDownloadSaveData_Email()
{
#if UNITY_EDITOR
yield return null;
GameManager.DB.DonwloadUnlockDataCount(100);
GameManager.DB.DonwloadGoldData(4000);
GameManager.DB.DonwloadHeartData(6);
GameManager.DB.DonwloadKeyData(5);
GameManager.DB.DownloadLevel(2);
GameManager.DB.DownloadIsRemoveADS(true);
OnDownloadSaveData?.Invoke(true);
#else
if (user == null)
{
Task<AuthResult> signInTask = OnSignIn_Email();
if (signInTask.IsCompleted == false)
{
yield return new WaitUntil(() => signInTask.IsCompleted);
}
if (signInTask.IsCompletedSuccessfully == true)
{
user = signInTask.Result.User;
OnAccountSignIn?.Invoke(true);
isLoginFail = false;
Debug.Log("AccountManager: Sign In Successful.");
sb.Append("AccountManager: Welcome: ").Append(signInTask.Result.User.Email);
Debug.Log(sb.ToString());
Firebase.FirebaseApp.LogLevel = Firebase.LogLevel.Debug;
Firebase.Analytics.FirebaseAnalytics.SetAnalyticsCollectionEnabled(true);
Crashlytics.ReportUncaughtExceptionsAsFatal = true;
Firebase.Analytics.FirebaseAnalytics.SetUserProperty(
Firebase.Analytics.FirebaseAnalytics.UserPropertySignUpMethod,
"Google");
if (auth.CurrentUser != null)
{
Firebase.Analytics.FirebaseAnalytics.SetUserId(auth.CurrentUser.UserId);
}
}
else
{
yield break;
}
}
downloadCoroutine = StartCoroutine(DownloadSaveData());
#endif
}
private void OnSignOut_Email()
{
Debug.Log("AccountManager: Calling SignOut");
auth.SignOut();
Firebase.Analytics.FirebaseAnalytics.SetAnalyticsCollectionEnabled(false);
Crashlytics.ReportUncaughtExceptionsAsFatal = false;
isLoginFail = false;
user = null;
OnAccountSignOut?.Invoke(true);
}
}