CapersProject/Assets/02.Scripts/FirebaseManager.cs
2025-01-02 19:44:51 +09:00

192 lines
7.8 KiB
C#

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<FirebaseManager>
{
private DatabaseReference _reference;
public List<BlueWaterRankUserData> UserDatas;
private string _lastDatasName;
[SerializeField]
private TycoonResultUi resultUi;
public BlueWaterRankUserData thisUser;
protected override void OnAwake()
{
_reference = FirebaseDatabase.DefaultInstance.RootReference;
UserDatas = new List<BlueWaterRankUserData>();
}
private void OnDestroy()
{
UserDatas.Clear();
}
[Button("랭크 최신화")]
async Task UpdateUserData(Action action = null)
{
UserDatas.Clear();
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("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) return;
_ = UpdateUserData(() =>
{
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);
int i = 0;
for (; i < 102; i++) //__Root포함 탐색 (최대 랭크 100위 + Root + 자기자신 = 102)
{
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);
}
[Button("이름변경하기")]
public void WirteUserDataName(string changename) //이름변경
{
_reference.Child("Users").Child(thisUser.Id).Child("Name").SetValueAsync(changename);
}
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;
}
}
}