using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Threading.Tasks; using BlueWater.Tycoons; using BlueWater.Uis; using ExcelDataReader.Log; using Firebase.Database; using Firebase.Extensions; using UnityEngine; using Sirenix.OdinInspector; using UnityEngine.Serialization; namespace BlueWater { public class BlueWaterRankUserData { public string Id { get; set; } //저장시에만 사용함. public string Name { get; set; } public int Round { get; set; } public int Gold { get; set; } public int Time { get; set; } public int Tries { get; set; } public string NextID { get; set; } } public class FirebaseManager : Singleton { private DatabaseReference _reference; public List UserDatas; private string _lastDatasName; [NonSerialized] public TycoonResultUi resultUi; public BlueWaterRankUserData thisUser; protected override void OnAwake() { _reference = FirebaseDatabase.DefaultInstance.RootReference; UserDatas = new List(); } private void OnDestroy() { UserDatas.Clear(); } public FirebaseManager GetFirebaseManger() { return this; } async Task UpdateUserData(Action action = null) { UserDatas.Clear(); UserDatas = new List(); var snapshot = await FirebaseDatabase.DefaultInstance.GetReference("Users").GetValueAsync(); string nextID = "__Root"; for (int i = 0; i < snapshot.ChildrenCount; i++) { try { var child = snapshot.Child(nextID); if (child == null) { break; // 유효하지 않으면 루프 종료 } BlueWaterRankUserData user = new BlueWaterRankUserData { Name = child.Child("Name")?.Value?.ToString() ?? "Unknown", Round = int.Parse(child.Child("Round")?.Value?.ToString() ?? "0"), Gold = int.Parse(child.Child("Gold")?.Value?.ToString() ?? "0"), Time = int.Parse(child.Child("Time")?.Value?.ToString() ?? "0"), Tries = int.Parse(child.Child("Tries")?.Value?.ToString() ?? "0"), NextID = child.Child("NextID")?.Value?.ToString() }; nextID = user.NextID; if (string.IsNullOrEmpty(nextID)) { //Debug.Log($"Name : {user.Name} / Round : {user.Round} / Gold : {user.Gold} / Time : {user.Time}"); //Debug.Log("NextNAME END"); break; // 다음 nextID 유효하지 않으면 루프 종료 } // Debug.Log($"Name : {user.Name} / Round : {user.Round} / Gold : {user.Gold} / Time : {user.Time}"); // Debug.Log("ADD"); UserDatas.Add(user); } catch (Exception ex) { // Debug.LogError($"Exception occurred: {ex.Message}"); break; } } action?.Invoke(); // 데이터 로딩 완료 시 호출 } public void CreateRank(Action action = null) { // 통신 가능 여부 체크 if (Application.internetReachability == NetworkReachability.NotReachable) {Debug.Log("Network ERROR!!"); return;} _ = UpdateUserData(() => { Debug.Log("Start Set this User"); thisUser = new BlueWaterRankUserData(); thisUser.Id = GetOriginalUserID(); thisUser.Round = int.Parse(TycoonManager.Instance.GetCurrentLevelData().Idx); thisUser.Gold = resultUi._goldSpent; thisUser.Time = (int)resultUi._playTime; thisUser.Tries = ES3.Load(SaveData.Tries, 0); Debug.Log("End Set this User"); int i = 0; for (; i < 102; i++) //__Root포함 탐색 (최대 랭크 100위 + Root + 자기자신 = 102) { Debug.Log(i); if (i < UserDatas.Count) { if (UserDatas[i].Round > thisUser.Round) {continue;} if (UserDatas[i].Round == thisUser.Round && UserDatas[i].Gold > thisUser.Gold) {continue;} if (UserDatas[i].Round == thisUser.Round && UserDatas[i].Gold == thisUser.Gold && UserDatas[i].Time < thisUser.Time) {continue;} if (UserDatas[i].Round == thisUser.Round && UserDatas[i].Gold == thisUser.Gold && UserDatas[i].Time == thisUser.Time && UserDatas[i].Tries <= thisUser.Tries) {continue;} //100위까지 랭크가 기입되어 있고 100위권 안에 들어갔을때 //마지막 항목은 삭제... if (UserDatas.Count >= 100) //__Root포함 100개 { //Debug.Log("Remove : " + UserDatas[^2].NextID); _reference.Child("Users").Child(UserDatas[^2].NextID).RemoveValueAsync(); //삭제 } UserDatas.Insert(i , thisUser); } else if (i >= 101) { UserDatas.Add(thisUser);break;} //랭크 밖... 101위 else{ UserDatas.Add(thisUser); } //랭크 등록갯수가 100개 미만일경우 if (i == 1) //__Root(1등) 처리 { _reference.Child("Users").Child("__Root").Child("NextID").SetValueAsync(thisUser.Id); thisUser.NextID = UserDatas[0].NextID; //Debug.Log("thisUser.NextID = " + thisUser.NextID); } else { _reference.Child("Users").Child(UserDatas[i - 2].NextID).Child("NextID").SetValueAsync(thisUser.Id); thisUser.NextID = UserDatas[i-1].NextID; //Debug.Log("thisUser.NextID = " + thisUser.NextID); } WriteUserData(thisUser); break; } thisUser.NextID = null; action?.Invoke(); }); } private void WriteUserData(BlueWaterRankUserData userData) { _reference.Child("Users").Child(userData.Id).Child("Name").SetValueAsync("Empty"); _reference.Child("Users").Child(userData.Id).Child("Round").SetValueAsync(userData.Round); _reference.Child("Users").Child(userData.Id).Child("Gold").SetValueAsync(userData.Gold); _reference.Child("Users").Child(userData.Id).Child("Time").SetValueAsync(userData.Time); _reference.Child("Users").Child(userData.Id).Child("Tries").SetValueAsync(userData.Tries); _reference.Child("Users").Child(userData.Id).Child("Language").SetValueAsync(CultureInfo.CurrentCulture.Name); _reference.Child("Users").Child(userData.Id).Child("NextID").SetValueAsync(userData.NextID); } public void WirteUserDataName(string changename) //이름변경 { _reference.Child("Users").Child(thisUser.Id).Child("Name").SetValueAsync(changename); } private string GetOriginalUserID() { string uniqueID = Environment.MachineName; DateTime utcNow = DateTime.UtcNow; TimeZoneInfo pstZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time"); DateTime pstTime = TimeZoneInfo.ConvertTimeFromUtc(utcNow, pstZone); uniqueID += pstTime.ToString("-yyyy-MM-dd-HH-mm-ss"); return uniqueID; } } }