PJ/Assets/scripts/dotfs_scripts/MANAGER_Mail.cs

214 lines
No EOL
8.1 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using Newtonsoft.Json;
using System.Linq;
public class MANAGER_Mail : MonoBehaviour
{
public static MANAGER_Mail Instance { get; private set; }
private const string MAIL_URL = "http://mc1.live-on.pro:64093/api/mail/mail.json";
private const string REWARDS_URL = "http://mc1.live-on.pro:64093/api/other/rewards_table_id.json";
// Данные сервера
public List<MailEntry> ActiveMails { get; private set; } = new List<MailEntry>();
public Dictionary<string, List<RewardItem>> RewardsTable { get; private set; } = new Dictionary<string, List<RewardItem>>();
// Состояние инициализации
public bool IsDataLoaded { get; private set; } = false;
private void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
private void Start()
{
StartCoroutine(LoadMailSystemData());
}
private IEnumerator LoadMailSystemData()
{
IsDataLoaded = false;
// 1. Загрузка конфигурации писем
UnityWebRequest mailReq = UnityWebRequest.Get(MAIL_URL);
yield return mailReq.SendWebRequest();
if (mailReq.result != UnityWebRequest.Result.Success)
{
yield break; // В реальном проекте здесь нужна логика ретрая
}
// 2. Загрузка таблицы наград
UnityWebRequest rewardsReq = UnityWebRequest.Get(REWARDS_URL);
yield return rewardsReq.SendWebRequest();
if (rewardsReq.result != UnityWebRequest.Result.Success)
{
yield break;
}
// 3. Десериализация
try
{
// 1. Десериализуем во временную обертку
var wrapper = JsonConvert.DeserializeObject<MailDataWrapper>(mailReq.downloadHandler.text);
// 2. Присваиваем список из обертки в ActiveMails
ActiveMails = wrapper != null ? wrapper.mails : new List<MailEntry>();
// Для наград (если там такая же структура с корневым объектом, проверьте rewards_table_id.json)
RewardsTable = JsonConvert.DeserializeObject<Dictionary<string, List<RewardItem>>>(rewardsReq.downloadHandler.text);
IsDataLoaded = true;
MANAGER_GameEvents.TriggerUIUpdate();
}
catch (System.Exception e)
{
}
}
public DateTime GetCurrentTime()
{
try
{
// Пытаемся получить локальное время устройства
return DateTime.Now;
}
catch
{
// Если по какой-то причине на Linux или другой ОС произошел сбой,
// берем UTC и прибавляем 7 часов (Красноярск)
return DateTime.UtcNow.AddHours(7);
}
}
public bool IsMailDeleted(string mailId)
{
return PlayerPrefs.GetInt($"Mail_Deleted_{mailId}", 0) == 1;
}
public void DeleteMail(string mailId)
{
PlayerPrefs.SetInt($"Mail_Deleted_{mailId}", 1);
PlayerPrefs.Save();
MANAGER_GameEvents.TriggerUIUpdate(); // Обновляем список, чтобы письмо исчезло
}
// --- ЛОГИКА СОСТОЯНИЙ (ПРОЧИТАНО / ЗАБРАНО) ---
public bool IsMailRead(string mailId)
{
return PlayerPrefs.GetInt($"Mail_Read_{mailId}", 0) == 1;
}
public void MarkAsRead(string mailId)
{
if (!IsMailRead(mailId))
{
PlayerPrefs.SetInt($"Mail_Read_{mailId}", 1);
PlayerPrefs.Save();
// Отправляем сигнал для визуального снятия метки "Новое"
MANAGER_GameEvents.TriggerUIUpdate();
}
}
// Добавьте это в MANAGER_Mail.cs
public string GetFormattedBody(MailEntry mail)
{
if (mail == null || mail.content == null) return "";
string body = mail.content.body;
// Проверяем наличие плейсхолдера
if (body.Contains("{today_reward}"))
{
string rewardText = "";
// Проверяем, есть ли ID таблицы наград и загружена ли она
if (!string.IsNullOrEmpty(mail.rewards_table_id) && RewardsTable.TryGetValue(mail.rewards_table_id, out var rewards))
{
// Собираем строку наград (например: "Золото x15, Меч x1")
// Здесь r.name — это то самое поле, которое мы договорились добавить в RewardItem
rewardText = string.Join(", ", rewards.Select(r => $"[g]x{r.amount} {r.name}[/c]"));
}
else
{
// Если награда не найдена, выводим заглушку или пустую строку
rewardText = "награды отсутствуют";
}
body = body.Replace("{today_reward}", rewardText);
}
return body;
}
private const int TEST_COOLDOWN_SECONDS = 86400;
public void ClaimReward(string mailId)
{
if (IsRewardClaimed(mailId)) return;
MailEntry mail = ActiveMails.FirstOrDefault(m => m.id == mailId);
if (mail != null)
{
// Сохраняем текущее время в формате Total Seconds
double totalSecondsNow = GetCurrentTime().Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
PlayerPrefs.SetString($"Mail_LastClaimedTime_{mailId}", totalSecondsNow.ToString());
PlayerPrefs.Save();
MarkAsRead(mailId);
MANAGER_GameEvents.TriggerUIUpdate();
}
}
public bool IsRewardClaimed(string mailId)
{
string lastClaimedStr = PlayerPrefs.GetString($"Mail_LastClaimedTime_{mailId}", "0");
double lastClaimedSeconds = double.Parse(lastClaimedStr);
double currentSeconds = GetCurrentTime().Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
// Письмо "забрано", если с момента последнего клика прошло МЕНЬШЕ 60 секунд
return (currentSeconds - lastClaimedSeconds) < TEST_COOLDOWN_SECONDS;
}
public List<MailEntry> GetAvailableMails()
{
return ActiveMails
.Where(mail =>
{
// Базовая фильтрация: удаленные и не подходящие по дате
if (IsMailDeleted(mail.id)) return false;
DateTime now = GetCurrentTime();
if (mail.logic.StartDate.HasValue && now < mail.logic.StartDate.Value) return false;
if (mail.logic.EndDate.HasValue && now > mail.logic.EndDate.Value) return false;
return true;
})
/* СОРТИРОВКА:
1. Сначала считаем приоритет:
Если награда ЗАБРАНА (IsRewardClaimed == true), ставим -99.
Если награда ДОСТУПНА, ставим 0 (или можно брать mail.priority, если он есть в классе).
*/
.OrderByDescending(mail => IsRewardClaimed(mail.id) ? -99 : 0)
// 2. Внутри групп (сначала новые/доступные) сортируем по дате начала
.ThenByDescending(mail => mail.logic.StartDate)
.ToList();
}
}