Files
better-genshin-impact/BetterGenshinImpact/GameTask/LogParse/TravelsDiaryDetailManager.cs
2025-09-23 00:59:07 +08:00

303 lines
12 KiB
C#
Raw 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.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using BetterGenshinImpact.Core.Config;
using BetterGenshinImpact.GameTask.Common;
using BetterGenshinImpact.Helpers;
using Microsoft.Extensions.Logging;
using Wpf.Ui.Violeta.Controls;
namespace BetterGenshinImpact.GameTask.LogParse;
public class TravelsDiaryDetailManager
{
public static List<(int year, int month)> GetInvolvedMonths(List<LogParse.ConfigGroupEntity> configGroups)
{
// HashSet 用于存储不重复的年份和月份
HashSet<(int year, int month)> involvedMonths = new HashSet<(int year, int month)>();
foreach (var group in configGroups)
{
// 如果 StartDate 有值,添加对应的年份和月份
if (group.StartDate.HasValue)
{
involvedMonths.Add((group.StartDate.Value.Year, group.StartDate.Value.Month));
}
// 如果 EndDate 有值,添加对应的年份和月份
if (group.EndDate.HasValue)
{
involvedMonths.Add((group.EndDate.Value.Year, group.EndDate.Value.Month));
}
}
// 返回按年份和月份排序的列表
return involvedMonths.OrderBy(m => m.year).ThenBy(m => m.month).ToList();
}
public static string basePath = Global.Absolute(@"log\logparse");
public static List<ActionItem> loadAllActionItems(GameInfo gameInfo, List<LogParse.ConfigGroupEntity> configGroups)
{
return loadAllActionItems(gameInfo,GetInvolvedMonths(configGroups));
}
public static List<ActionItem> loadAllActionItems(GameInfo gameInfo,List<(int year, int month)> ms)
{
//List<(int year, int month)> ms = GetInvolvedMonths(configGroups);
string tddPath = Global.Absolute(@$"{basePath}\{gameInfo.GameUid}\travelsdiarydetail");
List<ActionItem> actionItems = new List<ActionItem>();
foreach (var m in ms)
{
string tddfile = Global.Absolute($@"{tddPath}\{m.year}_{m.month}.json");
if (File.Exists(tddfile))
{
var _temp = JsonSerializer.Deserialize<ApiResponse<ActionItem>>(File.ReadAllText(tddfile));
if (_temp != null)
{
//统计杀怪或突发事件奖励
actionItems.AddRange(_temp.Data.List.Where(item => item.ActionId == 37 || item.ActionId == 28 || item.ActionId == 39));
}
}
}
return actionItems.OrderBy(m => DateTime.Parse(m.Time)).ToList();
}
private static List<(int year, int month)> GetMonthPairs()
{
DateTimeOffset now = ServerTimeHelper.GetServerTimeNow();
List<(int year, int month)> result = new List<(int, int)>();
if (now.Day == 1 && now.Hour < 4)
{
// 上个月
DateTimeOffset lastMonth = now.AddMonths(-1);
result.Add((lastMonth.Year, lastMonth.Month));
}
// 当前月
result.Add((now.Year, now.Month));
return result;
}
//取今天的札记数据
public static List<ActionItem> loadNowDayActionItems(GameInfo gameInfo)
{
//正序的
var sortedList = loadAllActionItems(gameInfo, GetMonthPairs());
DateTimeOffset now = ServerTimeHelper.GetServerTimeNow();
DateTimeOffset today4am = new DateTimeOffset(now.Year, now.Month, now.Day, 4, 0, 0, now.Offset);
DateTimeOffset startTime, endTime;
if (now < today4am)
{
// 现在是今天凌晨4点前区间是昨天4点 ~ 今天4点前
startTime = today4am.AddDays(-1);
endTime = today4am;
}
else
{
// 现在是今天4点后区间是今天4点 ~ 明天4点
startTime = today4am;
endTime = today4am.AddDays(1);
}
// 取出符合时间段的数据
var dayItems = sortedList
.Where(m =>
{
var time = DateTime.Parse(m.Time);
return time >= startTime && time < endTime;
})
.ToList();
return dayItems;
}
/*
* 增量更新,米游社札记摩拉记录
*/
public static async Task<GameInfo> UpdateTravelsDiaryDetailManager(string cookie,bool skipToast = false)
{
List<(int year, int month)> months = GetCurrentAndPreviousTwoMonths();
months.Reverse();
YsClient ys = new YsClient();
var apiResponse = await ys.GetGenshinGameRolesAsync(cookie);
GameInfo gameInfo = apiResponse.Data.List[0];
string tddPath = Global.Absolute(@$"{basePath}\{gameInfo.GameUid}\travelsdiarydetail");
try
{
for (int i = 0; i < months.Count; i++)
{
var month = months[i];
string tddfile = Global.Absolute($@"{tddPath}\{month.year}_{month.month}.json");
var fileExists = File.Exists(tddfile);
//文件存在,进行增量更新
if (i > 0 && fileExists)
{
bool canUpdate = true;
//上个月的如果这个月更新过,就不再更新了
if (i == 1 && IsFileModifiedThisMonth(tddfile))
{
canUpdate = false;
}
if (canUpdate)
{
// 读取文件内容
string jsonString2 = File.ReadAllText(tddfile);
//文件内容
var _temp = JsonSerializer.Deserialize<ApiResponse<ActionItem>>(jsonString2);
//增量
var _temp2 = await ys.GetTravelsDiaryDetailAsync(gameInfo, cookie, month.month, 2, 100, default,
_temp.Data.List[0]);
var addList = _temp2.Data.List;
_temp2.Data.List.AddRange(_temp.Data.List);
writeFile(tddfile, _temp2);
}
}
//文件不存在,全量更新
if (!fileExists)
{
var _temp2 = await ys.GetTravelsDiaryDetailAsync(gameInfo, cookie, month.month, 2);
writeFile(tddfile, _temp2);
if (!skipToast)
{
Toast.Information($"{month.year}_{month.month}数据获取成功!");
}
else
{
TaskControl.Logger.LogError($"米游社札记数据:{month.year}_{month.month}获取成功!");
}
}
/*else
{
var _temp = JsonSerializer.Deserialize<ApiResponse<ActionItem>>(File.ReadAllText(tddfile));
}*/
}
}
catch (NoLoginException e)
{
if (!skipToast)
{
Toast.Warning("token未登录请重新登录获取此次将不新最新数据");
}
else
{
TaskControl.Logger.LogError($"token未登录请重新登录获取此次将不新最新数据");
}
}
return gameInfo;
}
static void writeFile(string path, ApiResponse<ActionItem> apiResponse)
{
var options = new JsonSerializerOptions
{
WriteIndented = true // 启用格式化(缩进)
};
string jsonString = JsonSerializer.Serialize(apiResponse, options);
string directory = Path.GetDirectoryName(path);
// 如果目录不存在,则创建它
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
// 将格式化后的 JSON 写入文件
File.WriteAllText(path, jsonString);
}
static bool IsFileModifiedThisMonth(string filePath)
{
if (!File.Exists(filePath))
{
throw new FileNotFoundException("文件未找到", filePath);
}
// File.GetLastWriteTime 返回 DateTime 类型为 DateTimeKind.Local
DateTimeOffset lastModified =
new DateTimeOffset(File.GetLastWriteTime(filePath)).ToOffset(ServerTimeHelper.GetServerTimeOffset());
// 获取当前月份的开始和结束日期
DateTimeOffset now = ServerTimeHelper.GetServerTimeNow();
DateTimeOffset startOfMonth = new DateTimeOffset(now.Year, now.Month, 1, 0, 0, 0, now.Offset);
DateTimeOffset endOfMonth = startOfMonth.AddMonths(1).AddDays(-1);
// 判断文件最后修改时间是否在本月
return lastModified >= startOfMonth && lastModified <= endOfMonth;
}
static List<(int year, int month)> GetCurrentAndPreviousTwoMonths()
{
List<(int year, int month)> months = new List<(int year, int month)>();
DateTimeOffset now = ServerTimeHelper.GetServerTimeNow();
for (int i = 0; i < 3; i++)
{
int year = now.Year;
int month = now.Month - i;
// 如果月份小于 1则向前推一年并调整月份
if (month < 1)
{
month += 12;
year -= 1;
}
months.Add((year, month));
}
return months;
}
public static string generHtmlMessage()
{
string htmlContent = @"
<!DOCTYPE html>
<html lang='zh'>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<title>锄地统计说明</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
.content { padding: 20px; border-radius: 8px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); }
h1 { font-size: 24px; color: #333; }
p { font-size: 16px; color: #555; line-height: 1.6; }
a { color: #007bff; text-decoration: none; }
a:hover { text-decoration: underline; }
.cookie-input { margin-top: 15px; padding: 8px; width: 100%; max-width: 300px; border: 1px solid #ccc; border-radius: 4px; }
</style>
</head>
<body>
<div class='content'>
<h1>锄地统计说明</h1>
<p>锄地统计基于米游社旅行札记不实时有误差但不大需要获取米游社cookie参照下面地址获取</p>
<p><a href='https://www.bilibili.com/video/BV1Cr4y1e7wJ' target='_blank'>点此查看如何获取米游社Cookie</a></p>
<p>PC端获取一样登录后按F12输入上面页面中的代码(javascript:(function(){prompt('', document.cookie)})();),能更快的拿到。</p>
<p>按步骤获取cookie填入前面文本框。一次可管好多天如果提示未登录再次获取即可。</p>
<p>首次获取是全量获取最近3个月的数据会比较慢后续增量更新会快。</p>
</div>
</body>
</html>";
return htmlContent;
}
}