Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
4120561
add ServerResetTime struct
bhbghghbgb Sep 7, 2025
b70317d
add to setting page, converter for serialization
bhbghghbgb Sep 7, 2025
1d74694
entering text and selecting dropdown both work now
bhbghghbgb Sep 7, 2025
0023a0d
typeconverter not needed
bhbghghbgb Sep 7, 2025
cb334af
fix BlessingOfTheWelkinMoonTask to use ServerResetTime
bhbghghbgb Sep 7, 2025
3e35188
refactor ServerResetTime
bhbghghbgb Sep 8, 2025
4d44e08
write tests
bhbghghbgb Sep 8, 2025
80214a8
refactor 3 Task, 1 Config to use ServerResetTime Config
bhbghghbgb Sep 8, 2025
4043773
make clear of Default server time, and don't throw on parsing error
bhbghghbgb Sep 8, 2025
f4f7a81
add a server time zone configuration item
bhbghghbgb Sep 9, 2025
2d8cb28
create get server time helper, refactor 3 Tasks and 1 Config file to …
bhbghghbgb Sep 9, 2025
f19085c
cleanup ServerResetTime
bhbghghbgb Sep 9, 2025
6b59a0b
Merge remote-tracking branch 'upstream/main' into server-reset-time
bhbghghbgb Sep 9, 2025
7171c56
cleanup
bhbghghbgb Sep 9, 2025
2e04a75
expose server time zone offset to js
bhbghghbgb Sep 10, 2025
eafc2ea
Merge remote-tracking branch 'upstream/main' into server-reset-time
bhbghghbgb Sep 14, 2025
ea56f84
use TimeProvider to make testing easier, register it to DI, temporari…
bhbghghbgb Sep 14, 2025
2910764
remove temp code line comments
bhbghghbgb Sep 15, 2025
3e8f32d
translate docs and comments to Chinese
bhbghghbgb Sep 15, 2025
2176388
FarmingStatsRecorder internal refactor as it doesn't require user input
bhbghghbgb Sep 15, 2025
4fa85ee
ScriptGroupConfig->PathingPartyTaskCycleConfig->BoundaryTime add opti…
bhbghghbgb Sep 15, 2025
8c542bd
ExecutionRecordStorage->ExecutionRecord to store server time, ScriptG…
bhbghghbgb Sep 15, 2025
2bd9648
Merge remote-tracking branch 'upstream/main' into server-reset-time
bhbghghbgb Sep 15, 2025
7ca53e9
refactor TravelsDiaryDetailManager, expose helper method to return of…
bhbghghbgb Sep 16, 2025
7108c9e
ServerStartTime fallback to use config instead of assume, in case of …
bhbghghbgb Sep 17, 2025
2e3a9b8
Merge branch 'babalae:main' into server-reset-time
bhbghghbgb Sep 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions BetterGenshinImpact/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ public partial class App : Application
services.AddSingleton<HutaoNamedPipe>();
services.AddSingleton<BgiOnnxFactory>();
services.AddSingleton<OcrFactory>();

services.AddSingleton(TimeProvider.System);
services.AddSingleton<IServerTimeProvider, ServerTimeProvider>();

// Configuration
//services.Configure<AppConfig>(context.Configuration.GetSection(nameof(AppConfig)));
Expand Down Expand Up @@ -181,6 +184,7 @@ protected override async void OnStartup(StartupEventArgs e)
ConsoleHelper.AllocateConsole("BetterGI Console");
RegisterEvents();
await _host.StartAsync();
ServerTimeHelper.Initialize(_host.Services.GetRequiredService<IServerTimeProvider>());
await UrlProtocolHelper.RegisterAsync();
}
catch (Exception ex)
Expand Down
5 changes: 4 additions & 1 deletion BetterGenshinImpact/Core/Config/OneDragonFlowConfig.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using BetterGenshinImpact.GameTask;
using BetterGenshinImpact.Helpers;
using CommunityToolkit.Mvvm.ComponentModel;

namespace BetterGenshinImpact.Core.Config;
Expand Down Expand Up @@ -120,7 +122,8 @@ public partial class OneDragonFlowConfig : ObservableObject
{
if (WeeklyDomainEnabled)
{
var dayOfWeek = (DateTime.Now.Hour >= 4 ? DateTime.Today : DateTime.Today.AddDays(-1)).DayOfWeek;
var serverTime = ServerTimeHelper.GetServerTimeNow();
var dayOfWeek = (serverTime.Hour >= 4 ? serverTime : serverTime.AddDays(-1)).DayOfWeek;
return dayOfWeek switch
{
DayOfWeek.Monday => (MondayPartyName, MondayDomainName,SundaySelectedValue),
Expand Down
4 changes: 4 additions & 0 deletions BetterGenshinImpact/Core/Config/OtherConfig.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using BetterGenshinImpact.Core.Recognition;
using BetterGenshinImpact.Model;
using CommunityToolkit.Mvvm.ComponentModel;

namespace BetterGenshinImpact.Core.Config;
Expand All @@ -14,6 +15,9 @@ public partial class OtherConfig : ObservableObject
//自动领取派遣任务城市
[ObservableProperty]
private string _autoFetchDispatchAdventurersGuildCountry = "无";
//服务器时区偏移量
[ObservableProperty]
private TimeSpan _serverTimeZoneOffset = TimeSpan.FromHours(8);
[ObservableProperty]
private AutoRestart _autoRestartConfig = new();
//锄地规划
Expand Down
15 changes: 13 additions & 2 deletions BetterGenshinImpact/Core/Config/PathingPartyTaskCycleConfig.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using BetterGenshinImpact.Helpers;
using CommunityToolkit.Mvvm.ComponentModel;

namespace BetterGenshinImpact.Core.Config;
Expand All @@ -10,9 +11,13 @@ public partial class PathingPartyTaskCycleConfig : ObservableObject
[ObservableProperty]
private bool _enable = false;

//周期分界时间点
//周期分界时间点(小时),如果负数则不启用
[ObservableProperty]
private int _boundaryTime = 0;
// 分界时间是否基于服务器时间(否则基于本地时间)
[ObservableProperty]
private bool _isBoundaryTimeBasedOnServerTime = false;


//不同材料有不同的周期,按需配置,如矿石类是3、突破材料是2,或按照自已想几天执行一次配置即可
[ObservableProperty]
Expand All @@ -25,7 +30,7 @@ public partial class PathingPartyTaskCycleConfig : ObservableObject
private int _index = 1;


public int GetExecutionOrder(DateTime now)
public int GetExecutionOrder(DateTimeOffset now)
{
try
{
Expand Down Expand Up @@ -55,5 +60,11 @@ public int GetExecutionOrder(DateTime now)
}

}
public int GetExecutionOrder()
{
return GetExecutionOrder(IsBoundaryTimeBasedOnServerTime
? ServerTimeHelper.GetServerTimeNow()
: DateTimeOffset.Now);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ public partial class TaskCompletionSkipRuleConfig:ObservableObject
//周期分界时间点,如果负数则不启用,主要适用于固定时间的刷新物品适用
[ObservableProperty]
private int _boundaryTime = 4;
// 分界时间是否基于服务器时间(否则基于本地时间)
[ObservableProperty]
private bool _isBoundaryTimeBasedOnServerTime = false;

//上一次执行间隔时间,出于精度考虑,这里使用秒为单位
[ObservableProperty]
Expand Down
19 changes: 19 additions & 0 deletions BetterGenshinImpact/Core/Script/Dependence/ServerTime.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using BetterGenshinImpact.Helpers;

namespace BetterGenshinImpact.Core.Script.Dependence;

public static class ServerTime
{
/// <summary>
/// 获取服务器时区偏移量
/// </summary>
/// <returns>
/// 以毫秒为单位的偏移量
/// 该值可直接在JavaScript中使用:`new Date(Date.now() + offset)`
/// </returns>
public static int GetServerTimeZoneOffset()
{
return (int)ServerTimeHelper.GetServerTimeOffset().TotalMilliseconds;
}
}
3 changes: 2 additions & 1 deletion BetterGenshinImpact/Core/Script/EngineExtend.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ public static void InitHost(IScriptEngine engine, string workDir, string[]? sear

engine.AddHostObject("OpenCvSharp", new HostTypeCollection("OpenCvSharp"));


engine.AddHostType("ServerTime", typeof(ServerTime));



// 添加C#的类型
Expand Down
9 changes: 9 additions & 0 deletions BetterGenshinImpact/Core/Script/Group/ScriptGroupProject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using BetterGenshinImpact.GameTask.Common;
using BetterGenshinImpact.GameTask.FarmingPlan;
using BetterGenshinImpact.GameTask.LogParse;
using BetterGenshinImpact.Helpers;
using Microsoft.Extensions.Logging;

namespace BetterGenshinImpact.Core.Script.Group;
Expand Down Expand Up @@ -167,6 +168,10 @@ public async Task Run()
//执行记录
ExecutionRecord executionRecord = new ExecutionRecord()
{
ServerStartTime =
GroupInfo?.Config.PathingConfig.TaskCompletionSkipRuleConfig.IsBoundaryTimeBasedOnServerTime ?? false
? ServerTimeHelper.GetServerTimeNow()
: DateTimeOffset.Now,
StartTime = DateTime.Now,
GroupName = GroupInfo?.Name ?? "",
FolderName = FolderName,
Expand Down Expand Up @@ -280,6 +285,10 @@ public async Task Run()
executionRecord.IsSuccessful = true;
}

executionRecord.ServerEndTime =
GroupInfo?.Config.PathingConfig.TaskCompletionSkipRuleConfig.IsBoundaryTimeBasedOnServerTime ?? false
? ServerTimeHelper.GetServerTimeNow()
: DateTimeOffset.Now;
executionRecord.EndTime = DateTime.Now;
ExecutionRecordStorage.SaveExecutionRecord(executionRecord);
}
Expand Down
4 changes: 2 additions & 2 deletions BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -390,8 +390,8 @@ private async Task EnterDomain()
Logger.LogInformation("自动秘境:{Text}", "检测到秘境限时全开");
}

DateTime now = DateTime.Now;
if ((now.DayOfWeek == DayOfWeek.Sunday && now.Hour >= 4 || now.DayOfWeek == DayOfWeek.Monday && now.Hour < 4) || limitedFullyStringRaocrListdone != null)
var serverTime = ServerTimeHelper.GetServerTimeNow();
if (serverTime is { DayOfWeek: DayOfWeek.Sunday, Hour: >= 4 } || serverTime is { DayOfWeek: DayOfWeek.Monday, Hour: < 4 } || limitedFullyStringRaocrListdone != null)
{
using var artifactArea = CaptureToRectArea().Find(fightAssets.ArtifactAreaRa); //检测是否为圣遗物副本
if (artifactArea.IsEmpty())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Threading;
using System.Threading.Tasks;
using BetterGenshinImpact.GameTask.Model.Area;
using BetterGenshinImpact.Helpers;
using Microsoft.Extensions.Logging;
using static BetterGenshinImpact.GameTask.Common.TaskControl;

Expand All @@ -15,13 +16,12 @@ public class BlessingOfTheWelkinMoonTask
{
public string Name => "自动点击空月祝福";


public async Task Start(CancellationToken ct)
{
try
{
// 4点全程触发
if (DateTime.Now.Hour == 4)
if (ServerTimeHelper.GetServerTimeNow().Hour == 4)
{
using var ra = CaptureToRectArea();
if (Bv.IsInBlessingOfTheWelkinMoon(ra))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -476,8 +476,8 @@ private async Task GetReward(CancellationToken ct)
Logger.LogInformation("领取尘歌壶奖励:{text}", "未配置购买商店物品");
return;
}
DateTime now = DateTime.Now;
DayOfWeek currentDayOfWeek = now.Hour >= 4 ? now.DayOfWeek : now.AddDays(-1).DayOfWeek;
DateTimeOffset serverTime = ServerTimeHelper.GetServerTimeNow();
DayOfWeek currentDayOfWeek = serverTime.Hour >= 4 ? serverTime.DayOfWeek : serverTime.AddDays(-1).DayOfWeek;
DayOfWeek? configDayOfWeek = GetDayOfWeekFromConfig(SelectedConfig.SecretTreasureObjects.First());
if (configDayOfWeek.HasValue || SelectedConfig.SecretTreasureObjects.First() == "每天重复" && SelectedConfig.SecretTreasureObjects.Count > 1)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using BetterGenshinImpact.GameTask.AutoPathing.Model;
using BetterGenshinImpact.GameTask.Common;
using BetterGenshinImpact.GameTask.LogParse;
using BetterGenshinImpact.Helpers;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
Expand Down Expand Up @@ -212,8 +213,8 @@ public async static Task TryUpdateTravelsData()
public static DailyFarmingData ReadDailyFarmingData()
{
// 确定统计日期(以凌晨4点为分界)
DateTime now = DateTime.Now;
DateTime statsDate = CalculateStatsDate(now);
DateTimeOffset now = ServerTimeHelper.GetServerTimeNow();
DateTimeOffset statsDate = CalculateStatsDate(now);
string dateString = statsDate.ToString("yyyyMMdd");

// 确保目录存在
Expand All @@ -228,7 +229,7 @@ public static DailyFarmingData ReadDailyFarmingData()
/// <summary>
/// 计算统计日期(凌晨4点为分界)
/// </summary>
private static DateTime CalculateStatsDate(DateTime currentTime)
private static DateTime CalculateStatsDate(DateTimeOffset currentTime)
{
// 如果当前时间在4点之前,则算作前一天
return currentTime.Hour < 4 ? currentTime.Date.AddDays(-1) : currentTime.Date;
Expand Down
17 changes: 15 additions & 2 deletions BetterGenshinImpact/GameTask/LogParse/ExecutionRecord.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Runtime.Serialization;
using Newtonsoft.Json;

namespace BetterGenshinImpact.GameTask.LogParse;
Expand All @@ -12,13 +13,25 @@ public class ExecutionRecord
[JsonProperty("type")] public string Type = string.Empty;

/// <summary>
/// 执行开始时间
/// 执行开始时间(服务器时间,包含时区信息)
/// </summary>
[JsonProperty("server_start_time")]
public DateTimeOffset? ServerStartTime { get; set; }

/// <summary>
/// 执行开始时间的本地时间表示(用于向后兼容的统计显示)
/// </summary>
[JsonProperty("start_time")]
public DateTime StartTime { get; set; }

/// <summary>
/// 执行结束时间
/// 执行结束时间(服务器时间,包含时区信息)
/// </summary>
[JsonProperty("server_end_time")]
public DateTimeOffset? ServerEndTime { get; set; }

/// <summary>
/// 执行结束时间的本地时间表示(用于向后兼容的统计显示)
/// </summary>
[JsonProperty("end_time")]
public DateTime EndTime { get; set; }
Expand Down
19 changes: 13 additions & 6 deletions BetterGenshinImpact/GameTask/LogParse/ExecutionRecordStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.IO;
using BetterGenshinImpact.Core.Config;
using BetterGenshinImpact.Core.Script.Group;
using BetterGenshinImpact.Helpers;
using Newtonsoft.Json;

namespace BetterGenshinImpact.GameTask.LogParse;
Expand Down Expand Up @@ -140,16 +141,19 @@ private static int ConvertSecondsToDaysUp(int seconds)
/// <summary>
/// 根据自定义的一天开始时间判断日期是否属于"今天"
/// </summary>
/// <param name="boundaryHour">分界时间(小时),0-23之间</param>
/// <param name="targetDate">要判断的日期</param>
/// <returns>如果属于"今天"则返回true,否则返回false</returns>
private static bool IsTodayByBoundary(int boundaryHour, DateTime targetDate)
/// <param name="boundaryHour">分界时间(小时),0-23之间,基于<paramref name="isBoundaryTimeBasedOnServerTime"/>参数决定的时间参考系</param>
/// <param name="targetDate">要判断的日期(本地时间)</param>
/// <param name="isBoundaryTimeBasedOnServerTime">true表示使用服务器时间计算,false表示使用本地时间计算</param>
/// <returns>如果目标日期在根据分界时间定义的"今天"范围内则返回true,否则返回false</returns>
private static bool IsTodayByBoundary(int boundaryHour, DateTimeOffset targetDate, bool isBoundaryTimeBasedOnServerTime)
{
// 验证分界时间是否有效
if (boundaryHour < 0 || boundaryHour > 23)
throw new ArgumentOutOfRangeException(nameof(boundaryHour), "分界时间必须在0-23之间");

DateTime now = DateTime.Now;
DateTimeOffset now = isBoundaryTimeBasedOnServerTime
? ServerTimeHelper.GetServerTimeNow()
: DateTimeOffset.Now;

// 计算今天的开始时间(根据分界时间)
DateTime todayStart;
Expand Down Expand Up @@ -237,7 +241,10 @@ public static bool IsSkipTask(ScriptGroupProject project, out string message,Lis
if (boundaryTimeEnable)
{
// 如果记录不在"今天",则跳过
if (!IsTodayByBoundary(config.BoundaryTime, record.StartTime)) continue;
if (!IsTodayByBoundary(config.BoundaryTime,
record.ServerStartTime ??
new DateTimeOffset(record.StartTime).ToOffset(ServerTimeHelper.GetServerTimeOffset()),
config.IsBoundaryTimeBasedOnServerTime)) continue;
}

bool isMatchFound = false;
Expand Down
24 changes: 14 additions & 10 deletions BetterGenshinImpact/GameTask/LogParse/TravelsDiaryDetailManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Threading.Tasks;
using BetterGenshinImpact.Core.Config;
using BetterGenshinImpact.GameTask.Common;
using BetterGenshinImpact.Helpers;
using Microsoft.Extensions.Logging;
using Wpf.Ui.Violeta.Controls;

Expand Down Expand Up @@ -67,14 +68,14 @@ public static List<ActionItem> loadAllActionItems(GameInfo gameInfo,List<(int ye
}
private static List<(int year, int month)> GetMonthPairs()
{
DateTime now = DateTime.Now;
DateTimeOffset now = ServerTimeHelper.GetServerTimeNow();

List<(int year, int month)> result = new List<(int, int)>();

if (now.Day == 1 && now.Hour < 4)
{
// 上个月
DateTime lastMonth = now.AddMonths(-1);
DateTimeOffset lastMonth = now.AddMonths(-1);
result.Add((lastMonth.Year, lastMonth.Month));
}

Expand All @@ -90,10 +91,10 @@ public static List<ActionItem> loadNowDayActionItems(GameInfo gameInfo)
{
//正序的
var sortedList = loadAllActionItems(gameInfo, GetMonthPairs());
DateTime now = DateTime.Now;
DateTime today4am = now.Date.AddHours(4);
DateTimeOffset now = ServerTimeHelper.GetServerTimeNow();
DateTimeOffset today4am = new DateTimeOffset(now.Year, now.Month, now.Day, 4, 0, 0, now.Offset);

DateTime startTime, endTime;
DateTimeOffset startTime, endTime;

if (now < today4am)
{
Expand Down Expand Up @@ -231,11 +232,14 @@ static bool IsFileModifiedThisMonth(string filePath)
throw new FileNotFoundException("文件未找到", filePath);
}

DateTime lastModified = File.GetLastWriteTime(filePath);

// File.GetLastWriteTime 返回 DateTime 类型为 DateTimeKind.Local
DateTimeOffset lastModified =
new DateTimeOffset(File.GetLastWriteTime(filePath)).ToOffset(ServerTimeHelper.GetServerTimeOffset());

// 获取当前月份的开始和结束日期
DateTime startOfMonth = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
DateTime endOfMonth = startOfMonth.AddMonths(1).AddDays(-1);
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;
Expand All @@ -244,7 +248,7 @@ static bool IsFileModifiedThisMonth(string filePath)
static List<(int year, int month)> GetCurrentAndPreviousTwoMonths()
{
List<(int year, int month)> months = new List<(int year, int month)>();
DateTime now = DateTime.Now;
DateTimeOffset now = ServerTimeHelper.GetServerTimeNow();

for (int i = 0; i < 3; i++)
{
Expand Down
Loading