mirror of
https://github.com/babalae/better-genshin-impact.git
synced 2026-03-15 07:43:20 +08:00
重构服务器重置时间处理 (#2160)
This commit is contained in:
@@ -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)));
|
||||
@@ -181,6 +184,7 @@ public partial class App : Application
|
||||
ConsoleHelper.AllocateConsole("BetterGI Console");
|
||||
RegisterEvents();
|
||||
await _host.StartAsync();
|
||||
ServerTimeHelper.Initialize(_host.Services.GetRequiredService<IServerTimeProvider>());
|
||||
await UrlProtocolHelper.RegisterAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using BetterGenshinImpact.GameTask;
|
||||
using BetterGenshinImpact.Helpers;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace BetterGenshinImpact.Core.Config;
|
||||
@@ -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),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using BetterGenshinImpact.Core.Recognition;
|
||||
using BetterGenshinImpact.Model;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace BetterGenshinImpact.Core.Config;
|
||||
@@ -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();
|
||||
//锄地规划
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using BetterGenshinImpact.Helpers;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace BetterGenshinImpact.Core.Config;
|
||||
@@ -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]
|
||||
@@ -25,7 +30,7 @@ public partial class PathingPartyTaskCycleConfig : ObservableObject
|
||||
private int _index = 1;
|
||||
|
||||
|
||||
public int GetExecutionOrder(DateTime now)
|
||||
public int GetExecutionOrder(DateTimeOffset now)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -55,5 +60,11 @@ public partial class PathingPartyTaskCycleConfig : ObservableObject
|
||||
}
|
||||
|
||||
}
|
||||
public int GetExecutionOrder()
|
||||
{
|
||||
return GetExecutionOrder(IsBoundaryTimeBasedOnServerTime
|
||||
? ServerTimeHelper.GetServerTimeNow()
|
||||
: DateTimeOffset.Now);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,6 +19,9 @@ public partial class TaskCompletionSkipRuleConfig:ObservableObject
|
||||
//周期分界时间点,如果负数则不启用,主要适用于固定时间的刷新物品适用
|
||||
[ObservableProperty]
|
||||
private int _boundaryTime = 4;
|
||||
// 分界时间是否基于服务器时间(否则基于本地时间)
|
||||
[ObservableProperty]
|
||||
private bool _isBoundaryTimeBasedOnServerTime = false;
|
||||
|
||||
//上一次执行间隔时间,出于精度考虑,这里使用秒为单位
|
||||
[ObservableProperty]
|
||||
|
||||
19
BetterGenshinImpact/Core/Script/Dependence/ServerTime.cs
Normal file
19
BetterGenshinImpact/Core/Script/Dependence/ServerTime.cs
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,8 @@ public class EngineExtend
|
||||
|
||||
engine.AddHostObject("OpenCvSharp", new HostTypeCollection("OpenCvSharp"));
|
||||
|
||||
|
||||
engine.AddHostType("ServerTime", typeof(ServerTime));
|
||||
|
||||
|
||||
|
||||
// 添加C#的类型
|
||||
|
||||
@@ -19,6 +19,7 @@ using BetterGenshinImpact.GameTask.AutoPathing.Model.Enum;
|
||||
using BetterGenshinImpact.GameTask.Common;
|
||||
using BetterGenshinImpact.GameTask.FarmingPlan;
|
||||
using BetterGenshinImpact.GameTask.LogParse;
|
||||
using BetterGenshinImpact.Helpers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace BetterGenshinImpact.Core.Script.Group;
|
||||
@@ -167,6 +168,10 @@ public partial class ScriptGroupProject : ObservableObject
|
||||
//执行记录
|
||||
ExecutionRecord executionRecord = new ExecutionRecord()
|
||||
{
|
||||
ServerStartTime =
|
||||
GroupInfo?.Config.PathingConfig.TaskCompletionSkipRuleConfig.IsBoundaryTimeBasedOnServerTime ?? false
|
||||
? ServerTimeHelper.GetServerTimeNow()
|
||||
: DateTimeOffset.Now,
|
||||
StartTime = DateTime.Now,
|
||||
GroupName = GroupInfo?.Name ?? "",
|
||||
FolderName = FolderName,
|
||||
@@ -280,6 +285,10 @@ public partial class ScriptGroupProject : ObservableObject
|
||||
executionRecord.IsSuccessful = true;
|
||||
}
|
||||
|
||||
executionRecord.ServerEndTime =
|
||||
GroupInfo?.Config.PathingConfig.TaskCompletionSkipRuleConfig.IsBoundaryTimeBasedOnServerTime ?? false
|
||||
? ServerTimeHelper.GetServerTimeNow()
|
||||
: DateTimeOffset.Now;
|
||||
executionRecord.EndTime = DateTime.Now;
|
||||
ExecutionRecordStorage.SaveExecutionRecord(executionRecord);
|
||||
}
|
||||
|
||||
@@ -390,8 +390,8 @@ public class AutoDomainTask : ISoloTask
|
||||
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())
|
||||
|
||||
@@ -3,6 +3,7 @@ using System;
|
||||
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;
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -476,8 +476,8 @@ internal class GoToSereniteaPotTask
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -8,6 +8,7 @@ using BetterGenshinImpact.Core.Config;
|
||||
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;
|
||||
@@ -212,8 +213,8 @@ public static class FarmingStatsRecorder
|
||||
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");
|
||||
|
||||
// 确保目录存在
|
||||
@@ -228,7 +229,7 @@ public static class FarmingStatsRecorder
|
||||
/// <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;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BetterGenshinImpact.GameTask.LogParse;
|
||||
@@ -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; }
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using BetterGenshinImpact.Core.Config;
|
||||
using BetterGenshinImpact.Core.Script.Group;
|
||||
using BetterGenshinImpact.Helpers;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BetterGenshinImpact.GameTask.LogParse;
|
||||
@@ -140,16 +141,19 @@ public class ExecutionRecordStorage
|
||||
/// <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;
|
||||
@@ -237,7 +241,10 @@ public class ExecutionRecordStorage
|
||||
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;
|
||||
|
||||
@@ -6,6 +6,7 @@ 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;
|
||||
|
||||
@@ -67,14 +68,14 @@ public class TravelsDiaryDetailManager
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -90,10 +91,10 @@ public class TravelsDiaryDetailManager
|
||||
{
|
||||
//正序的
|
||||
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)
|
||||
{
|
||||
@@ -231,11 +232,14 @@ public class TravelsDiaryDetailManager
|
||||
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;
|
||||
@@ -244,7 +248,7 @@ public class TravelsDiaryDetailManager
|
||||
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++)
|
||||
{
|
||||
|
||||
117
BetterGenshinImpact/Helpers/ServerTimeHelper.cs
Normal file
117
BetterGenshinImpact/Helpers/ServerTimeHelper.cs
Normal file
@@ -0,0 +1,117 @@
|
||||
using System;
|
||||
using BetterGenshinImpact.GameTask;
|
||||
|
||||
namespace BetterGenshinImpact.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// 提供配置的服务器时区的当前时间
|
||||
/// </summary>
|
||||
public interface IServerTimeProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取调整到服务器时区偏移量的当前时间
|
||||
/// </summary>
|
||||
/// <returns>表示当前服务器时间的 <see cref="DateTimeOffset"/></returns>
|
||||
DateTimeOffset GetServerTimeNow();
|
||||
|
||||
/// <summary>
|
||||
/// 获取服务器时区偏移量
|
||||
/// </summary>
|
||||
/// <returns>表示服务器时区偏移量的 <see cref="TimeSpan"/></returns>
|
||||
TimeSpan GetServerTimeOffset();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IServerTimeProvider"/>
|
||||
/// <remarks>
|
||||
/// 此实现使用 <see cref="TimeProvider"/> 获取当前UTC时间,
|
||||
/// 然后应用配置的服务器时区偏移量
|
||||
/// </remarks>
|
||||
public class ServerTimeProvider : IServerTimeProvider
|
||||
{
|
||||
private readonly TimeProvider _timeProvider;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化 <see cref="ServerTimeProvider"/> 类的新实例
|
||||
/// </summary>
|
||||
/// <param name="timeProvider">用于获取基准UTC时间的 <see cref="TimeProvider"/></param>
|
||||
public ServerTimeProvider(TimeProvider timeProvider)
|
||||
{
|
||||
_timeProvider = timeProvider;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DateTimeOffset GetServerTimeNow()
|
||||
{
|
||||
var serverOffset = GetServerTimeOffset();
|
||||
return _timeProvider.GetUtcNow().ToOffset(serverOffset);
|
||||
}
|
||||
|
||||
public TimeSpan GetServerTimeOffset()
|
||||
{
|
||||
try
|
||||
{
|
||||
return TaskContext.Instance().Config.OtherConfig.ServerTimeZoneOffset;
|
||||
}
|
||||
// throw new Exception("Config未初始化"); in TaskContext.cs
|
||||
catch (Exception)
|
||||
{
|
||||
// 如果配置未加载,假定为北京时间用于核心开发者测试
|
||||
return TimeSpan.FromHours(8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 提供静态外观以便轻松访问服务器时间
|
||||
/// </summary>
|
||||
public static class ServerTimeHelper
|
||||
{
|
||||
private static IServerTimeProvider? _serverTimeProvider;
|
||||
|
||||
/// <summary>
|
||||
/// 使用具体的 <see cref="IServerTimeProvider"/> 实现初始化静态辅助类
|
||||
/// 此方法必须在应用程序启动期间调用一次
|
||||
/// </summary>
|
||||
/// <param name="serverTimeProvider">用于检索服务器时间的提供程序</param>
|
||||
/// <exception cref="ArgumentNullException">当 <paramref name="serverTimeProvider"/> 为 null 时抛出</exception>
|
||||
public static void Initialize(IServerTimeProvider serverTimeProvider)
|
||||
{
|
||||
_serverTimeProvider = serverTimeProvider ?? throw new ArgumentNullException(nameof(serverTimeProvider));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取调整到服务器时区偏移量的当前时间
|
||||
/// </summary>
|
||||
/// <returns>表示当前服务器时间的 <see cref="DateTimeOffset"/></returns>
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// 如果尚未调用 <see cref="Initialize"/> 则抛出
|
||||
/// </exception>
|
||||
public static DateTimeOffset GetServerTimeNow()
|
||||
{
|
||||
if (_serverTimeProvider is null)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"{nameof(ServerTimeHelper)} 尚未初始化。请先调用 {nameof(Initialize)}。");
|
||||
}
|
||||
|
||||
return _serverTimeProvider.GetServerTimeNow();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取服务器时区偏移量
|
||||
/// </summary>
|
||||
/// <returns>表示服务器时区偏移量的 <see cref="TimeSpan"/></returns>
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// 如果尚未调用 <see cref="Initialize"/> 则抛出
|
||||
/// </exception>
|
||||
public static TimeSpan GetServerTimeOffset()
|
||||
{
|
||||
if (_serverTimeProvider is null)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"{nameof(ServerTimeHelper)} 尚未初始化。请先调用 {nameof(Initialize)}。");
|
||||
}
|
||||
|
||||
return _serverTimeProvider.GetServerTimeOffset();
|
||||
}
|
||||
}
|
||||
@@ -63,7 +63,7 @@ public partial class ScriptService : IScriptService
|
||||
var tcc = project.GroupInfo.Config.PathingConfig.TaskCycleConfig;
|
||||
if (tcc.Enable)
|
||||
{
|
||||
int index = tcc.GetExecutionOrder(DateTime.Now);
|
||||
int index = tcc.GetExecutionOrder();
|
||||
if (index == -1)
|
||||
{
|
||||
_logger.LogInformation($"{project.Name}周期配置参数错误,配置将不生效,任务正常执行!");
|
||||
|
||||
@@ -1026,6 +1026,35 @@
|
||||
Margin="0,0,36,0"
|
||||
IsChecked="{Binding Config.OtherConfig.RestoreFocusOnLostEnabled, Mode=TwoWay}" />-->
|
||||
</Grid>
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ui:TextBlock Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
FontTypography="Body"
|
||||
Text="服务器时区设置"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="设置游戏服务器的时区,用于计算基于服务器时间的每日重置时间等任务调度。JS脚本可手动使用此设置来处理不同区域服务器的时区。"
|
||||
TextWrapping="Wrap" />
|
||||
<ComboBox Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
MinWidth="100"
|
||||
Margin="0,0,36,0"
|
||||
ItemsSource="{Binding ServerTimeZones}"
|
||||
SelectedValue="{Binding Config.OtherConfig.ServerTimeZoneOffset}"
|
||||
SelectedValuePath="Item1"
|
||||
DisplayMemberPath="Item2" />
|
||||
</Grid>
|
||||
<ui:CardExpander Margin="0,0,0,12"
|
||||
ContentPadding="0"
|
||||
Icon="{ui:SymbolIcon SquareHintSparkles24}">
|
||||
|
||||
@@ -416,6 +416,31 @@
|
||||
MinWidth="120"
|
||||
Text="{Binding PathingConfig.TaskCycleConfig.BoundaryTime}" />
|
||||
</Grid>
|
||||
<Grid Margin="16,0,16,16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ui:TextBlock Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
FontTypography="Body"
|
||||
Text="分界时间参考服务器时区"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="启用后,上面的分界时间将基于“服务器时区设置”计算。不启用则使用电脑本地时间(旧版行为)。"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:ToggleSwitch Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,36,0"
|
||||
IsChecked="{Binding PathingConfig.TaskCycleConfig.IsBoundaryTimeBasedOnServerTime}" />
|
||||
</Grid>
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
@@ -591,6 +616,31 @@
|
||||
MinWidth="120"
|
||||
Text="{Binding PathingConfig.TaskCompletionSkipRuleConfig.BoundaryTime}" />
|
||||
</Grid>
|
||||
<Grid Margin="16,0,16,16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ui:TextBlock Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
FontTypography="Body"
|
||||
Text="分界时间参考服务器时区"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="启用后,上面的分界时间将基于“服务器时区设置”计算。不启用则使用电脑本地时间(旧版行为)。"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:ToggleSwitch Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,36,0"
|
||||
IsChecked="{Binding PathingConfig.TaskCompletionSkipRuleConfig.IsBoundaryTimeBasedOnServerTime}" />
|
||||
</Grid>
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
|
||||
@@ -50,6 +50,13 @@ public partial class CommonSettingsPageViewModel : ViewModel
|
||||
|
||||
private string _selectedCountry = string.Empty;
|
||||
[ObservableProperty] private List<string> _adventurersGuildCountry = ["无", "枫丹", "稻妻", "璃月", "蒙德"];
|
||||
|
||||
[ObservableProperty] private List<Tuple<TimeSpan, string>> _serverTimeZones =
|
||||
[
|
||||
Tuple.Create(TimeSpan.FromHours(8), "其他 UTC+08"),
|
||||
Tuple.Create(TimeSpan.FromHours(1), "欧服 UTC+01"),
|
||||
Tuple.Create(TimeSpan.FromHours(-5), "美服 UTC-05")
|
||||
];
|
||||
|
||||
public CommonSettingsPageViewModel(IConfigService configService, INavigationService navigationService,
|
||||
NotificationService notificationService)
|
||||
@@ -66,7 +73,7 @@ public partial class CommonSettingsPageViewModel : ViewModel
|
||||
public AllConfig Config { get; set; }
|
||||
public ObservableCollection<string> CountryList { get; } = new();
|
||||
public ObservableCollection<string> Areas { get; } = new();
|
||||
|
||||
|
||||
public ObservableCollection<string> MapPathingTypes { get; } = ["SIFT", "TemplateMatch"];
|
||||
|
||||
[ObservableProperty] private FrozenDictionary<string, string> _languageDict =
|
||||
@@ -106,11 +113,11 @@ public partial class CommonSettingsPageViewModel : ViewModel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<PaddleOcrModelConfig> PaddleOcrModelConfigs { get; } = new(Enum.GetValues(typeof(PaddleOcrModelConfig)).Cast<PaddleOcrModelConfig>());
|
||||
|
||||
[ObservableProperty]
|
||||
private PaddleOcrModelConfig _selectedPaddleOcrModelConfig;
|
||||
public ObservableCollection<PaddleOcrModelConfig> PaddleOcrModelConfigs { get; } =
|
||||
new(Enum.GetValues(typeof(PaddleOcrModelConfig)).Cast<PaddleOcrModelConfig>());
|
||||
|
||||
[ObservableProperty] private PaddleOcrModelConfig _selectedPaddleOcrModelConfig;
|
||||
|
||||
[RelayCommand]
|
||||
public void OnQuestionButtonOnClick()
|
||||
@@ -127,10 +134,11 @@ public partial class CommonSettingsPageViewModel : ViewModel
|
||||
cookieWin.NavigateToHtml(TravelsDiaryDetailManager.generHtmlMessage());
|
||||
cookieWin.Show();
|
||||
}
|
||||
|
||||
private void InitializeMiyousheCookie()
|
||||
{
|
||||
OtherConfig.Miyoushe mcfg = TaskContext.Instance().Config.OtherConfig.MiyousheConfig;
|
||||
if (mcfg.Cookie == string.Empty&&
|
||||
if (mcfg.Cookie == string.Empty &&
|
||||
mcfg.LogSyncCookie)
|
||||
{
|
||||
var config = LogParse.LoadConfig();
|
||||
@@ -339,6 +347,7 @@ public partial class CommonSettingsPageViewModel : ViewModel
|
||||
{
|
||||
await App.ServiceProvider.GetRequiredService<OcrFactory>().Unload();
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task OnPaddleOcrModelConfigChanged(PaddleOcrModelConfig value)
|
||||
{
|
||||
|
||||
@@ -75,7 +75,7 @@ public partial class ScriptGroupConfigViewModel : ObservableObject, IViewModel
|
||||
[RelayCommand]
|
||||
public void OnGetExecutionOrder()
|
||||
{
|
||||
var index = _pathingConfig.TaskCycleConfig.GetExecutionOrder(DateTime.Now);
|
||||
var index = _pathingConfig.TaskCycleConfig.GetExecutionOrder();
|
||||
if (index == -1)
|
||||
{
|
||||
Toast.Error("计算失败,请检查参数!");
|
||||
|
||||
Reference in New Issue
Block a user