mirror of
https://github.com/babalae/better-genshin-impact.git
synced 2026-05-21 09:45:48 +08:00
Merge branch 'main' into refactor/captureMat
This commit is contained in:
@@ -57,6 +57,8 @@ public class TpTask(CancellationToken ct)
|
||||
public async Task TpToStatueOfTheSeven()
|
||||
{
|
||||
await CheckInBigMapUi();
|
||||
|
||||
// 提前调整至恰当的缩放以更快的传送
|
||||
if (_tpConfig.MapZoomEnabled)
|
||||
{
|
||||
double currentZoomLevel = GetBigMapZoomLevel(CaptureToRectArea());
|
||||
@@ -73,22 +75,23 @@ public class TpTask(CancellationToken ct)
|
||||
string? area = _tpConfig.ReviveStatueOfTheSevenArea;
|
||||
double x = _tpConfig.ReviveStatueOfTheSevenPointX;
|
||||
double y = _tpConfig.ReviveStatueOfTheSevenPointY;
|
||||
GiTpPosition revivePoint = _tpConfig.ReviveStatueOfTheSeven ?? GetNearestGoddess(x, y);
|
||||
if (_tpConfig.IsReviveInNearestStatueOfTheSeven)
|
||||
{
|
||||
var center = GetBigMapCenterPoint();
|
||||
var giTpPoint = GetNearestGoddess(center.X, center.Y);
|
||||
if (giTpPoint != null)
|
||||
{
|
||||
country = giTpPoint.Country;
|
||||
area = giTpPoint.Area;
|
||||
x = giTpPoint.X;
|
||||
y = giTpPoint.Y;
|
||||
}
|
||||
country = giTpPoint.Country;
|
||||
area = giTpPoint.Area;
|
||||
x = giTpPoint.X;
|
||||
y = giTpPoint.Y;
|
||||
revivePoint = giTpPoint;
|
||||
}
|
||||
|
||||
Logger.LogInformation("将传送至 {country} {area} 七天神像", country, area);
|
||||
await Tp(x, y);
|
||||
if (_tpConfig.ShouldMove || _tpConfig.IsReviveInNearestStatueOfTheSeven)
|
||||
{
|
||||
(x, y) = GetClosestPoint(revivePoint.TranX, revivePoint.TranY, x, y, 5);
|
||||
var waypoint = new Waypoint
|
||||
{
|
||||
X = x,
|
||||
@@ -98,18 +101,45 @@ public class TpTask(CancellationToken ct)
|
||||
};
|
||||
var waypointForTrack = new WaypointForTrack(waypoint);
|
||||
await new PathExecutor(ct).MoveTo(waypointForTrack);
|
||||
Simulation.SendInput.SimulateAction(GIActions.Drop);
|
||||
}
|
||||
|
||||
await Delay((int)(_tpConfig.HpRestoreDuration * 1000), ct);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="tranX"> 传送后实际到达的点X坐标 </param>
|
||||
/// <param name="tranY"> 传送后实际到达的点Y坐标 </param>
|
||||
/// <param name="x"> 传送点 X 坐标 </param>
|
||||
/// <param name="y"> 传送点 Y 坐标 </param>
|
||||
/// <param name="d"> 期望最终离传送点的距离 </param>
|
||||
/// <returns> </returns>
|
||||
private static (double X, double Y) GetClosestPoint(double tranX, double tranY, double x, double y, double d)
|
||||
{
|
||||
double dx = x - tranX;
|
||||
double dy = y - tranY;
|
||||
double distanceSquared = dx * dx + dy * dy;
|
||||
double distance = Math.Sqrt(distanceSquared);
|
||||
d = d > 0 ? d : 0;
|
||||
if (distance < d)
|
||||
{
|
||||
return (tranX, tranY);
|
||||
}
|
||||
double ratio = d / distance;
|
||||
double px = (x - dx * ratio);
|
||||
double py = (y - dy * ratio);
|
||||
return (px, py);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取离 x,y 最近的七天神像
|
||||
/// </summary>
|
||||
/// <param name="x"></param>
|
||||
/// <param name="y"></param>
|
||||
/// <returns></returns>
|
||||
private GiTpPosition? GetNearestGoddess(double x, double y)
|
||||
private GiTpPosition GetNearestGoddess(double x, double y)
|
||||
{
|
||||
GiTpPosition? nearestGiTpPosition = null;
|
||||
double minDistance = double.MaxValue;
|
||||
@@ -123,7 +153,7 @@ public class TpTask(CancellationToken ct)
|
||||
}
|
||||
}
|
||||
// 获取最近的神像位置
|
||||
return nearestGiTpPosition;
|
||||
return nearestGiTpPosition ?? throw new InvalidOperationException("没找到最近的七天神像");;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -108,6 +108,7 @@ namespace LogParse
|
||||
{
|
||||
configTask.Fault.ReviveCount++;
|
||||
}
|
||||
|
||||
//传送失败,重试 n 次
|
||||
result = parseBgiLine($@"传送失败,重试 (\d+) 次", logstr);
|
||||
if (result.Item1)
|
||||
@@ -115,19 +116,31 @@ namespace LogParse
|
||||
configTask.Fault.TeleportFailCount = int.Parse(result.Item2[1]);
|
||||
|
||||
}
|
||||
|
||||
//战斗超时结束
|
||||
if (logstr == "战斗超时结束")
|
||||
{
|
||||
configTask.Fault.BattleTimeoutCount ++;
|
||||
}
|
||||
}
|
||||
|
||||
//重试一次路线或放弃此路线!
|
||||
if (logstr.EndsWith("重试一次路线或放弃此路线!"))
|
||||
{
|
||||
configTask.Fault.RetryCount++;
|
||||
configTask.Fault.RetryCount ++;
|
||||
}
|
||||
|
||||
//疑似卡死,尝试脱离...
|
||||
if (logstr == "疑似卡死,尝试脱离...")
|
||||
{
|
||||
configTask.Fault.StuckCount ++;
|
||||
}
|
||||
|
||||
//One or more errors occurred
|
||||
result = parseBgiLine(@"执行脚本时发生异常: ""(.+?)""", logstr);
|
||||
if (result.Item1)
|
||||
{
|
||||
configTask.Fault.ErrCount ++;
|
||||
}
|
||||
|
||||
if (logstr.StartsWith("→ 脚本执行结束: \"" + configTask.Name + "\""))
|
||||
{
|
||||
@@ -241,11 +254,14 @@ namespace LogParse
|
||||
public int ReviveCount { get; set; } = 0;
|
||||
//传送失败次数
|
||||
public int TeleportFailCount { get; set; } = 0;
|
||||
//疑似卡死次数
|
||||
public int StuckCount { get; set; } = 0;
|
||||
//重试次数
|
||||
public int RetryCount { get; set; } = 0;
|
||||
//战斗超时
|
||||
public int BattleTimeoutCount { get; set; } = 0;
|
||||
|
||||
//异常发生次数
|
||||
public int ErrCount { get; set; } = 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -401,8 +417,10 @@ namespace LogParse
|
||||
{
|
||||
colConfigList.Add((name: "复活次数", value: task => FormatNumberWithStyle(task.Fault.ReviveCount)));
|
||||
colConfigList.Add((name: "重试次数", value: task => FormatNumberWithStyle(task.Fault.RetryCount)));
|
||||
colConfigList.Add((name: "疑似卡死次数", value: task => FormatNumberWithStyle(task.Fault.StuckCount)));
|
||||
colConfigList.Add((name: "战斗超时次数", value: task => FormatNumberWithStyle(task.Fault.BattleTimeoutCount)));
|
||||
colConfigList.Add((name: "传送失败次数", value: task => FormatNumberWithStyle(task.Fault.TeleportFailCount)));
|
||||
colConfigList.Add((name: "异常发生次数", value: task => FormatNumberWithStyle(task.Fault.ErrCount)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using System;
|
||||
using System.DirectoryServices.ActiveDirectory;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace BetterGenshinImpact.Service.Notification;
|
||||
|
||||
@@ -10,187 +9,174 @@ namespace BetterGenshinImpact.Service.Notification;
|
||||
[Serializable]
|
||||
public partial class NotificationConfig : ObservableObject
|
||||
{
|
||||
|
||||
|
||||
[ObservableProperty]
|
||||
private string _notificationEventSubscribe = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private bool _webhookEnabled;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private string _webhookEndpoint = string.Empty;
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 是否包含截图
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private bool _includeScreenShot = true;
|
||||
|
||||
/// <summary>
|
||||
/// windows uwp 通知是否启用
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private bool _windowsUwpNotificationEnabled = false;
|
||||
|
||||
|
||||
// 飞书通知
|
||||
/// <summary>
|
||||
/// 飞书通知是否启用
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private bool _feishuNotificationEnabled = false;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 飞书通知地址
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private string _feishuWebhookUrl = string.Empty;
|
||||
|
||||
|
||||
// 企业微信通知
|
||||
/// <summary>
|
||||
/// 企业微信通知是否启用
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private bool _workweixinNotificationEnabled = false;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 企业微信通知通知地址
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private string _workweixinWebhookUrl = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
bool _webSocketNotificationEnabled = false;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _webSocketEndpoint = string.Empty;
|
||||
|
||||
// Email 通知配置
|
||||
[ObservableProperty]
|
||||
private bool _emailNotificationEnabled = false;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _smtpServer = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private int _smtpPort;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _smtpUsername = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _smtpPassword = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _fromEmail = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _fromName = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _toEmail = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Bark移动推送通知配置
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private bool _barkNotificationEnabled = false;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _barkApiEndpoint = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _barkDeviceKeys = string.Empty;
|
||||
|
||||
// Bark 通知附加参数配置
|
||||
|
||||
/// <summary>
|
||||
/// 推送副标题
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private string _barkSubtitle = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 推送中断级别:critical(重要警告), active(默认值), timeSensitive(时效性通知), passive(仅添加到通知列表)
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private string _barkLevel = "active";
|
||||
|
||||
/// <summary>
|
||||
/// 通知声音
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private string _barkSound = "minuet";
|
||||
|
||||
/// <summary>
|
||||
/// 重要警告的通知音量,取值范围: 0-10
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private int _barkVolume = 5;
|
||||
|
||||
/// <summary>
|
||||
/// 推送角标,可以是任意数字
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private int _barkBadge = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 通知铃声重复播放,1为开启
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private string _barkCall = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// iOS14.5以下自动复制推送内容,1为开启
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private string _barkAutoCopy = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 复制推送时指定复制的内容
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private string _barkCopy = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 为推送设置自定义图标URL
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private string _barkIcon = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 对消息进行分组,推送将按group分组显示在通知中心中
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private string _barkGroup = "default";
|
||||
|
||||
/// <summary>
|
||||
/// 传1保存推送,传其他的不保存推送
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private string _barkIsArchive = "1";
|
||||
|
||||
/// <summary>
|
||||
/// 点击推送时跳转的URL
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private string _barkUrl = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 传"none"时,点击推送不会弹窗
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private string _barkAction = string.Empty;
|
||||
[ObservableProperty] private string _barkAction = string.Empty;
|
||||
|
||||
[ObservableProperty] private string _barkApiEndpoint = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// iOS14.5以下自动复制推送内容,1为开启
|
||||
/// </summary>
|
||||
[ObservableProperty] private string _barkAutoCopy = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 推送角标,可以是任意数字
|
||||
/// </summary>
|
||||
[ObservableProperty] private int _barkBadge = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 通知铃声重复播放,1为开启
|
||||
/// </summary>
|
||||
[ObservableProperty] private string _barkCall = string.Empty;
|
||||
|
||||
[ObservableProperty] private string _barkCiphertext = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 复制推送时指定复制的内容
|
||||
/// </summary>
|
||||
[ObservableProperty] private string _barkCopy = string.Empty;
|
||||
|
||||
[ObservableProperty] private string _barkDeviceKeys = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 对消息进行分组,推送将按group分组显示在通知中心中
|
||||
/// </summary>
|
||||
[ObservableProperty] private string _barkGroup = "default";
|
||||
|
||||
/// <summary>
|
||||
/// 为推送设置自定义图标URL
|
||||
/// </summary>
|
||||
[ObservableProperty] private string _barkIcon = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 传1保存推送,传其他的不保存推送
|
||||
/// </summary>
|
||||
[ObservableProperty] private string _barkIsArchive = "1";
|
||||
|
||||
/// <summary>
|
||||
/// 推送中断级别:critical(重要警告), active(默认值), timeSensitive(时效性通知), passive(仅添加到通知列表)
|
||||
/// </summary>
|
||||
[ObservableProperty] private string _barkLevel = "active";
|
||||
|
||||
/// <summary>
|
||||
/// Bark移动推送通知配置
|
||||
/// </summary>
|
||||
[ObservableProperty] private bool _barkNotificationEnabled;
|
||||
|
||||
/// <summary>
|
||||
/// 通知声音
|
||||
/// </summary>
|
||||
[ObservableProperty] private string _barkSound = "minuet";
|
||||
|
||||
// Bark 通知附加参数配置
|
||||
|
||||
/// <summary>
|
||||
/// 推送副标题
|
||||
/// </summary>
|
||||
[ObservableProperty] private string _barkSubtitle = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 点击推送时跳转的URL
|
||||
/// </summary>
|
||||
[ObservableProperty] private string _barkUrl = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 重要警告的通知音量,取值范围: 0-10
|
||||
/// </summary>
|
||||
[ObservableProperty] private int _barkVolume = 5;
|
||||
|
||||
// Email 通知配置
|
||||
[ObservableProperty] private bool _emailNotificationEnabled;
|
||||
|
||||
|
||||
// 飞书通知
|
||||
/// <summary>
|
||||
/// 飞书通知是否启用
|
||||
/// </summary>
|
||||
[ObservableProperty] private bool _feishuNotificationEnabled;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 飞书通知地址
|
||||
/// </summary>
|
||||
[ObservableProperty] private string _feishuWebhookUrl = string.Empty;
|
||||
|
||||
[ObservableProperty] private string _fromEmail = string.Empty;
|
||||
|
||||
[ObservableProperty] private string _fromName = string.Empty;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 是否包含截图
|
||||
/// </summary>
|
||||
[ObservableProperty] private bool _includeScreenShot = true;
|
||||
|
||||
|
||||
[ObservableProperty] private string _notificationEventSubscribe = string.Empty;
|
||||
|
||||
[ObservableProperty] private string _smtpPassword = string.Empty;
|
||||
|
||||
[ObservableProperty] private int _smtpPort;
|
||||
|
||||
[ObservableProperty] private string _smtpServer = string.Empty;
|
||||
|
||||
[ObservableProperty] private string _smtpUsername = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Telegram API基础URL(可选,留空使用官方API)
|
||||
/// </summary>
|
||||
[ObservableProperty] private string _telegramApiBaseUrl = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Telegram机器人Token
|
||||
/// </summary>
|
||||
[ObservableProperty] private string _telegramBotToken = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Telegram聊天ID
|
||||
/// </summary>
|
||||
[ObservableProperty] private string _telegramChatId = string.Empty;
|
||||
|
||||
// Telegram通知
|
||||
/// <summary>
|
||||
/// Telegram通知是否启用
|
||||
/// </summary>
|
||||
[ObservableProperty] private bool _telegramNotificationEnabled;
|
||||
|
||||
[ObservableProperty] private string _toEmail = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
[ObservableProperty] private bool _webhookEnabled;
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
[ObservableProperty] private string _webhookEndpoint = string.Empty;
|
||||
|
||||
|
||||
[ObservableProperty] private string _webhookSendTo = string.Empty; // 修改属性名
|
||||
|
||||
[ObservableProperty] private string _webSocketEndpoint = string.Empty;
|
||||
|
||||
[ObservableProperty] private bool _webSocketNotificationEnabled;
|
||||
|
||||
/// <summary>
|
||||
/// windows uwp 通知是否启用
|
||||
/// </summary>
|
||||
[ObservableProperty] private bool _windowsUwpNotificationEnabled;
|
||||
|
||||
|
||||
// 企业微信通知
|
||||
/// <summary>
|
||||
/// 企业微信通知是否启用
|
||||
/// </summary>
|
||||
[ObservableProperty] private bool _workweixinNotificationEnabled;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 企业微信通知通知地址
|
||||
/// </summary>
|
||||
[ObservableProperty] private string _workweixinWebhookUrl = string.Empty;
|
||||
}
|
||||
@@ -6,11 +6,17 @@ using Microsoft.Extensions.Hosting;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Net.Http;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BetterGenshinImpact.GameTask;
|
||||
using BetterGenshinImpact.GameTask.Common;
|
||||
using BetterGenshinImpact.Service.Notification.Model;
|
||||
using BetterGenshinImpact.Service.Notification.Model.Enum;
|
||||
using BetterGenshinImpact.Service.Notifier;
|
||||
using BetterGenshinImpact.Service.Notifier.Exception;
|
||||
using BetterGenshinImpact.Service.Notifier.Interface;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Text.Json;
|
||||
using OpenCvSharp.Extensions;
|
||||
@@ -31,16 +37,6 @@ public class NotificationService : IHostedService
|
||||
InitializeNotifiers();
|
||||
}
|
||||
|
||||
public static NotificationService Instance()
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
throw new Exception("Not instantiated");
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
@@ -51,12 +47,20 @@ public class NotificationService : IHostedService
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public static NotificationService Instance()
|
||||
{
|
||||
if (_instance == null) throw new Exception("Not instantiated");
|
||||
|
||||
return _instance;
|
||||
}
|
||||
|
||||
|
||||
private void InitializeNotifiers()
|
||||
{
|
||||
if (TaskContext.Instance().Config.NotificationConfig.WebhookEnabled)
|
||||
{
|
||||
_notifierManager.RegisterNotifier(new WebhookNotifier(NotifyHttpClient, TaskContext.Instance().Config.NotificationConfig.WebhookEndpoint));
|
||||
_notifierManager.RegisterNotifier(new WebhookNotifier(NotifyHttpClient,
|
||||
TaskContext.Instance().Config.NotificationConfig));
|
||||
}
|
||||
|
||||
if (TaskContext.Instance().Config.NotificationConfig.WindowsUwpNotificationEnabled)
|
||||
@@ -66,37 +70,37 @@ public class NotificationService : IHostedService
|
||||
|
||||
if (TaskContext.Instance().Config.NotificationConfig.FeishuNotificationEnabled)
|
||||
{
|
||||
_notifierManager.RegisterNotifier(new FeishuNotifier(NotifyHttpClient, TaskContext.Instance().Config.NotificationConfig.FeishuWebhookUrl));
|
||||
_notifierManager.RegisterNotifier(new FeishuNotifier(NotifyHttpClient,
|
||||
TaskContext.Instance().Config.NotificationConfig.FeishuWebhookUrl));
|
||||
}
|
||||
|
||||
if (TaskContext.Instance().Config.NotificationConfig.WorkweixinNotificationEnabled)
|
||||
{
|
||||
_notifierManager.RegisterNotifier(new WorkWeixinNotifier(NotifyHttpClient, TaskContext.Instance().Config.NotificationConfig.WorkweixinWebhookUrl));
|
||||
_notifierManager.RegisterNotifier(new WorkWeixinNotifier(NotifyHttpClient,
|
||||
TaskContext.Instance().Config.NotificationConfig.WorkweixinWebhookUrl));
|
||||
}
|
||||
|
||||
// WebSocket通知初始化
|
||||
if (TaskContext.Instance().Config.NotificationConfig.WebSocketNotificationEnabled)
|
||||
// WebSocket通知初始化
|
||||
if (TaskContext.Instance().Config.NotificationConfig.WebSocketNotificationEnabled)
|
||||
{
|
||||
var jsonSerializerOptions = new JsonSerializerOptions
|
||||
{
|
||||
var jsonSerializerOptions = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower,
|
||||
};
|
||||
var cts = new CancellationTokenSource();
|
||||
_notifierManager.RegisterNotifier(new WebSocketNotifier(
|
||||
TaskContext.Instance().Config.NotificationConfig.WebSocketEndpoint,
|
||||
jsonSerializerOptions,
|
||||
cts
|
||||
));
|
||||
}
|
||||
PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower
|
||||
};
|
||||
var cts = new CancellationTokenSource();
|
||||
_notifierManager.RegisterNotifier(new WebSocketNotifier(
|
||||
TaskContext.Instance().Config.NotificationConfig.WebSocketEndpoint,
|
||||
jsonSerializerOptions,
|
||||
cts
|
||||
));
|
||||
}
|
||||
|
||||
// Bark通知初始化
|
||||
if (TaskContext.Instance().Config.NotificationConfig.BarkNotificationEnabled)
|
||||
{
|
||||
_notifierManager.RegisterNotifier(new BarkNotifier(
|
||||
TaskContext.Instance().Config.NotificationConfig.BarkDeviceKeys,
|
||||
TaskContext.Instance().Config.NotificationConfig.BarkApiEndpoint
|
||||
));
|
||||
}
|
||||
// Bark通知初始化
|
||||
if (TaskContext.Instance().Config.NotificationConfig.BarkNotificationEnabled)
|
||||
_notifierManager.RegisterNotifier(new BarkNotifier(
|
||||
TaskContext.Instance().Config.NotificationConfig.BarkDeviceKeys,
|
||||
TaskContext.Instance().Config.NotificationConfig.BarkApiEndpoint
|
||||
));
|
||||
|
||||
// 邮件通知初始化
|
||||
if (TaskContext.Instance().Config.NotificationConfig.EmailNotificationEnabled)
|
||||
@@ -111,6 +115,15 @@ public class NotificationService : IHostedService
|
||||
TaskContext.Instance().Config.NotificationConfig.ToEmail
|
||||
));
|
||||
}
|
||||
|
||||
// Telegram通知初始化
|
||||
if (TaskContext.Instance().Config.NotificationConfig.TelegramNotificationEnabled)
|
||||
_notifierManager.RegisterNotifier(new TelegramNotifier(
|
||||
NotifyHttpClient, // 使用共享的HttpClient
|
||||
TaskContext.Instance().Config.NotificationConfig.TelegramBotToken,
|
||||
TaskContext.Instance().Config.NotificationConfig.TelegramChatId,
|
||||
TaskContext.Instance().Config.NotificationConfig.TelegramApiBaseUrl
|
||||
));
|
||||
}
|
||||
|
||||
public void RefreshNotifiers()
|
||||
@@ -191,4 +204,4 @@ public class NotificationService : IHostedService
|
||||
{
|
||||
NotifyHttpClient.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,6 @@
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Mail;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@@ -9,23 +12,15 @@ namespace BetterGenshinImpact.Service.Notifier
|
||||
{
|
||||
public class EmailNotifier : INotifier
|
||||
{
|
||||
public string Name { get; set; } = "Email";
|
||||
|
||||
// SMTP服务器配置
|
||||
private readonly string _smtpServer;
|
||||
private readonly int _smtpPort;
|
||||
private readonly string _smtpUsername;
|
||||
private readonly string _smtpPassword;
|
||||
|
||||
// 发件人配置
|
||||
private readonly string _fromEmail;
|
||||
private readonly string _fromName;
|
||||
|
||||
// 收件人邮箱
|
||||
public string ToEmail { get; set; }
|
||||
private readonly string _smtpPassword;
|
||||
private readonly int _smtpPort;
|
||||
|
||||
// 提升 SmtpClient 为类的成员变量
|
||||
private readonly SmtpClient _smtpClient;
|
||||
// SMTP服务器配置
|
||||
private readonly string _smtpServer;
|
||||
private readonly string _smtpUsername;
|
||||
|
||||
public EmailNotifier(
|
||||
string smtpServer,
|
||||
@@ -44,14 +39,15 @@ namespace BetterGenshinImpact.Service.Notifier
|
||||
_fromName = fromName;
|
||||
ToEmail = toEmail;
|
||||
|
||||
// 在构造函数中初始化 SmtpClient
|
||||
_smtpClient = new SmtpClient(_smtpServer, _smtpPort)
|
||||
{
|
||||
Credentials = new System.Net.NetworkCredential(_smtpUsername, _smtpPassword),
|
||||
EnableSsl = true
|
||||
};
|
||||
// 忽略SSL证书验证错误
|
||||
ServicePointManager.ServerCertificateValidationCallback =
|
||||
delegate { return true; };
|
||||
}
|
||||
|
||||
// 收件人邮箱
|
||||
public string ToEmail { get; set; }
|
||||
public string Name { get; set; } = "Email";
|
||||
|
||||
public async Task SendAsync(BaseNotificationData content)
|
||||
{
|
||||
if (string.IsNullOrEmpty(ToEmail))
|
||||
@@ -59,24 +55,78 @@ namespace BetterGenshinImpact.Service.Notifier
|
||||
throw new NotifierException("收件人邮箱地址为空");
|
||||
}
|
||||
|
||||
try
|
||||
// 创建一个新的SmtpClient实例(不复用)
|
||||
using (var smtpClient = new SmtpClient())
|
||||
{
|
||||
using var mailMessage = new MailMessage
|
||||
try
|
||||
{
|
||||
From = new MailAddress(_fromEmail, _fromName),
|
||||
Subject = FormatEmailSubject(content),
|
||||
Body = FormatEmailBody(content),
|
||||
IsBodyHtml = true
|
||||
};
|
||||
|
||||
mailMessage.To.Add(ToEmail);
|
||||
// 配置SMTP客户端
|
||||
smtpClient.Host = _smtpServer;
|
||||
smtpClient.Port = _smtpPort;
|
||||
smtpClient.EnableSsl = true;
|
||||
smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
|
||||
smtpClient.UseDefaultCredentials = false;
|
||||
smtpClient.Credentials = new NetworkCredential(_smtpUsername, _smtpPassword);
|
||||
smtpClient.Timeout = 30000; // 30秒超时
|
||||
|
||||
// 使用成员变量 _smtpClient 发送邮件
|
||||
await _smtpClient.SendMailAsync(mailMessage);
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
throw new NotifierException($"发送邮件失败: {ex.Message}");
|
||||
// 创建邮件
|
||||
using (var mailMessage = new MailMessage())
|
||||
{
|
||||
mailMessage.From = new MailAddress(_fromEmail, _fromName);
|
||||
mailMessage.To.Add(ToEmail);
|
||||
mailMessage.Subject = FormatEmailSubject(content);
|
||||
mailMessage.Body = FormatEmailBody(content);
|
||||
mailMessage.IsBodyHtml = true;
|
||||
mailMessage.BodyEncoding = Encoding.UTF8;
|
||||
mailMessage.SubjectEncoding = Encoding.UTF8;
|
||||
|
||||
// 添加图片附件(如果存在)
|
||||
if (content.Screenshot != null)
|
||||
{
|
||||
var tempPath = Path.GetTempFileName() + ".jpg";
|
||||
try
|
||||
{
|
||||
// 保存图片到临时文件
|
||||
content.Screenshot.Save(tempPath, ImageFormat.Jpeg);
|
||||
|
||||
// 从文件添加附件
|
||||
var attachment = new Attachment(tempPath);
|
||||
mailMessage.Attachments.Add(attachment);
|
||||
|
||||
// 发送邮件
|
||||
await smtpClient.SendMailAsync(mailMessage);
|
||||
|
||||
// 清理附件和临时文件
|
||||
attachment.Dispose();
|
||||
if (File.Exists(tempPath)) File.Delete(tempPath);
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
// 尝试清理临时文件
|
||||
try
|
||||
{
|
||||
if (File.Exists(tempPath)) File.Delete(tempPath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
/* 忽略清理错误 */
|
||||
}
|
||||
|
||||
throw new NotifierException($"发送邮件失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 没有图片时直接发送
|
||||
await smtpClient.SendMailAsync(mailMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
var errorMessage = $"发送邮件失败: {ex.Message}";
|
||||
throw new NotifierException(errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,23 +139,29 @@ namespace BetterGenshinImpact.Service.Notifier
|
||||
private string FormatEmailBody(BaseNotificationData content)
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
builder.AppendLine("<html><body>");
|
||||
|
||||
builder.AppendLine("<html><body style='font-family: Arial, sans-serif;'>");
|
||||
|
||||
// 添加通知标题
|
||||
builder.AppendLine("<h2>通知详情</h2>");
|
||||
|
||||
builder.AppendLine("<h2 style='color: #333;'>通知详情</h2>");
|
||||
|
||||
// 添加通知内容
|
||||
foreach (var prop in content.GetType().GetProperties())
|
||||
{
|
||||
// 跳过Screenshot属性,它会单独处理
|
||||
if (prop.Name == "Screenshot")
|
||||
continue;
|
||||
|
||||
var value = prop.GetValue(content);
|
||||
if (value != null)
|
||||
{
|
||||
builder.AppendLine($"<p><strong>{prop.Name}:</strong> {value}</p>");
|
||||
builder.AppendFormat("<p><strong>{0}:</strong> {1}</p>", prop.Name, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 添加提示信息
|
||||
builder.AppendLine("<p><em>如有截图,请查看附件。</em></p>");
|
||||
builder.AppendLine("</body></html>");
|
||||
return builder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
226
BetterGenshinImpact/Service/Notifier/TelegramNotifier.cs
Normal file
226
BetterGenshinImpact/Service/Notifier/TelegramNotifier.cs
Normal file
@@ -0,0 +1,226 @@
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using BetterGenshinImpact.Service.Notification.Model;
|
||||
using BetterGenshinImpact.Service.Notifier.Exception;
|
||||
using BetterGenshinImpact.Service.Notifier.Interface;
|
||||
|
||||
namespace BetterGenshinImpact.Service.Notifier;
|
||||
|
||||
public class TelegramNotifier : INotifier, IDisposable
|
||||
{
|
||||
// 永远不更改此URL常量,这是Telegram API的标准URL前缀
|
||||
private const string TELEGRAM_API_URL = "https://api.telegram.org/bot";
|
||||
private readonly bool _createdHttpClient;
|
||||
private readonly HttpClient _httpClient;
|
||||
|
||||
private readonly JsonSerializerOptions _jsonSerializerOptions = new()
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 创建一个新的Telegram通知器实例
|
||||
/// </summary>
|
||||
/// <param name="httpClient">可选的HttpClient,如果不提供则创建新的</param>
|
||||
/// <param name="telegramBotToken">Telegram机器人Token</param>
|
||||
/// <param name="telegramChatId">Telegram聊天ID</param>
|
||||
/// <param name="telegramApiBaseUrl">不再使用,保留参数仅为兼容性</param>
|
||||
public TelegramNotifier(HttpClient httpClient = null, string telegramBotToken = "", string telegramChatId = "",
|
||||
string telegramApiBaseUrl = "")
|
||||
{
|
||||
TelegramBotToken = telegramBotToken;
|
||||
TelegramChatId = telegramChatId;
|
||||
|
||||
if (httpClient != null)
|
||||
{
|
||||
_httpClient = httpClient;
|
||||
_createdHttpClient = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpClient = new HttpClient();
|
||||
_createdHttpClient = true;
|
||||
_httpClient.Timeout = TimeSpan.FromSeconds(30);
|
||||
}
|
||||
|
||||
// 忽略自定义API URL,始终使用标准Telegram API URL
|
||||
TelegramApiBaseUrl = TELEGRAM_API_URL;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Telegram机器人Token
|
||||
/// </summary>
|
||||
public string TelegramBotToken { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Telegram聊天ID
|
||||
/// </summary>
|
||||
public string TelegramChatId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Telegram API基础URL - 内部使用
|
||||
/// </summary>
|
||||
private string TelegramApiBaseUrl { get; set; }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_createdHttpClient)
|
||||
{
|
||||
_httpClient?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通知器名称
|
||||
/// </summary>
|
||||
public string Name { get; set; } = "Telegram";
|
||||
|
||||
public async Task SendAsync(BaseNotificationData content)
|
||||
{
|
||||
if (string.IsNullOrEmpty(TelegramBotToken))
|
||||
{
|
||||
throw new NotifierException("Telegram bot token is not set");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(TelegramChatId))
|
||||
{
|
||||
throw new NotifierException("Telegram chat ID is not set");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var message = content.Message;
|
||||
var fullMessage = !string.IsNullOrEmpty(message) ? message : "";
|
||||
|
||||
if (!string.IsNullOrEmpty(fullMessage))
|
||||
{
|
||||
await SendTextMessageAsync(fullMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotifierException("No message content to send");
|
||||
}
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
throw new NotifierException("Network error sending Telegram notification: " + ex.Message);
|
||||
}
|
||||
catch (TaskCanceledException)
|
||||
{
|
||||
throw new NotifierException("Telegram API request timed out. Check your internet connection.");
|
||||
}
|
||||
catch (NotifierException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
throw new NotifierException("Error sending Telegram notification: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SendTextMessageAsync(string message)
|
||||
{
|
||||
// 构建Telegram API URL - 固定格式:https://api.telegram.org/bot{token}/sendMessage
|
||||
var endpoint = $"{TELEGRAM_API_URL}{TelegramBotToken}/sendMessage";
|
||||
|
||||
try
|
||||
{
|
||||
var jsonContent = new
|
||||
{
|
||||
chat_id = TelegramChatId,
|
||||
text = message,
|
||||
disable_web_page_preview = true
|
||||
};
|
||||
|
||||
var json = JsonSerializer.Serialize(jsonContent, _jsonSerializerOptions);
|
||||
var content = new StringContent(json, Encoding.UTF8, "application/json");
|
||||
|
||||
var request = new HttpRequestMessage(HttpMethod.Post, endpoint)
|
||||
{
|
||||
Content = content
|
||||
};
|
||||
|
||||
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||
request.Headers.UserAgent.Add(new ProductInfoHeaderValue("BetterGenshinImpact", "1.0"));
|
||||
|
||||
var response = await _httpClient.SendAsync(request);
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
throw new NotifierException(
|
||||
$"Telegram message failed with code: {response.StatusCode}, Error: {responseContent}");
|
||||
}
|
||||
|
||||
// Check for API errors in the response
|
||||
var (isSuccess, errorCode, errorDescription) = ValidateApiResponse(responseContent);
|
||||
|
||||
if (!isSuccess)
|
||||
{
|
||||
if (errorCode == 400)
|
||||
{
|
||||
throw new NotifierException(
|
||||
"Please send a message to the bot first and check that the chat ID is correct.");
|
||||
}
|
||||
|
||||
if (errorCode == 401)
|
||||
{
|
||||
throw new NotifierException("Telegram bot token is incorrect.");
|
||||
}
|
||||
|
||||
if (errorCode == 404)
|
||||
throw new NotifierException(
|
||||
$"Telegram API not found (404). Please verify your bot token is correct. URL: {endpoint}");
|
||||
|
||||
throw new NotifierException($"Telegram API error: {errorDescription} (Code: {errorCode})");
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex) when (!(ex is NotifierException))
|
||||
{
|
||||
throw new NotifierException("Error sending Telegram notification: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private (bool isSuccess, int errorCode, string errorDescription) ValidateApiResponse(string responseJson)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var doc = JsonDocument.Parse(responseJson))
|
||||
{
|
||||
var root = doc.RootElement;
|
||||
|
||||
// Telegram API returns "ok": true for success
|
||||
if (root.TryGetProperty("ok", out var okElement))
|
||||
{
|
||||
var isOk = okElement.GetBoolean();
|
||||
|
||||
if (!isOk)
|
||||
{
|
||||
var errorDescription = "Unknown Telegram API error";
|
||||
if (root.TryGetProperty("description", out var descriptionElement))
|
||||
errorDescription = descriptionElement.GetString();
|
||||
|
||||
var errorCode = 0;
|
||||
if (root.TryGetProperty("error_code", out var errorCodeElement))
|
||||
errorCode = errorCodeElement.GetInt32();
|
||||
|
||||
return (false, errorCode, errorDescription);
|
||||
}
|
||||
|
||||
return (true, 0, string.Empty);
|
||||
}
|
||||
|
||||
return (false, 0, "Invalid API response: 'ok' field missing");
|
||||
}
|
||||
}
|
||||
catch (JsonException ex)
|
||||
{
|
||||
return (false, 0, "Failed to parse API response: " + ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Net.WebSockets;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
@@ -53,6 +53,7 @@ namespace BetterGenshinImpact.Service.Notifier
|
||||
var json = JsonSerializer.Serialize(notificationData, _jsonSerializerOptions);
|
||||
var buffer = System.Text.Encoding.UTF8.GetBytes(json);
|
||||
await _webSocket.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, _cts.Token);
|
||||
await CloseAsync(); // 添加关闭连接的代码
|
||||
}
|
||||
catch (WebSocketException ex)
|
||||
{
|
||||
@@ -82,4 +83,4 @@ namespace BetterGenshinImpact.Service.Notifier
|
||||
await SendAsync(notificationData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
using BetterGenshinImpact.Service.Notifier.Exception;
|
||||
using BetterGenshinImpact.Service.Notifier.Exception;
|
||||
using BetterGenshinImpact.Service.Notifier.Interface;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using BetterGenshinImpact.Service.Notification.Model;
|
||||
using System.Collections.Generic;
|
||||
using BetterGenshinImpact.Service.Notification; // 添加对 System.Collections.Generic 命名空间的引用
|
||||
using BetterGenshinImpact.Service.Notification; // 添加对 NotificationConfig 类型的引用
|
||||
|
||||
namespace BetterGenshinImpact.Service.Notifier;
|
||||
|
||||
@@ -14,6 +17,9 @@ public class WebhookNotifier : INotifier
|
||||
|
||||
public string Endpoint { get; set; }
|
||||
|
||||
// 添加 send_to 属性
|
||||
private string SendTo { get; set; }
|
||||
|
||||
private readonly HttpClient _httpClient;
|
||||
|
||||
private readonly JsonSerializerOptions _jsonSerializerOptions = new()
|
||||
@@ -21,10 +27,12 @@ public class WebhookNotifier : INotifier
|
||||
PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower,
|
||||
};
|
||||
|
||||
public WebhookNotifier(HttpClient httpClient, string endpoint = "")
|
||||
public WebhookNotifier(HttpClient httpClient, NotificationConfig config)
|
||||
{
|
||||
|
||||
_httpClient = httpClient;
|
||||
Endpoint = endpoint;
|
||||
Endpoint = config.WebhookEndpoint;
|
||||
SendTo = config.WebhookSendTo; // 初始化 send_to 属性
|
||||
}
|
||||
|
||||
public async Task SendAsync(BaseNotificationData content)
|
||||
@@ -53,11 +61,21 @@ public class WebhookNotifier : INotifier
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private StringContent TransformData(BaseNotificationData notificationData)
|
||||
{
|
||||
// using object type here so it serializes the interface correctly
|
||||
var serializedData = JsonSerializer.Serialize<object>(notificationData, _jsonSerializerOptions);
|
||||
// 使用 SendTo 属性来设置 send_to 字段,并将 notification_data 的内容合并到外层字典
|
||||
var dataToSend = new Dictionary<string, object>
|
||||
{
|
||||
{ "send_to", SendTo },
|
||||
{ "event", notificationData.Event },
|
||||
{ "result", notificationData.Result },
|
||||
{ "timestamp", notificationData.Timestamp },
|
||||
{ "screenshot", notificationData.Screenshot },
|
||||
{ "message", notificationData.Message },
|
||||
{ "data", notificationData.Data }
|
||||
};
|
||||
|
||||
var serializedData = JsonSerializer.Serialize(dataToSend, _jsonSerializerOptions);
|
||||
|
||||
return new StringContent(serializedData, Encoding.UTF8, "application/json");
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
FontFamily="{StaticResource TextThemeFontFamily}"
|
||||
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
|
||||
mc:Ignorable="d">
|
||||
|
||||
|
||||
<StackPanel Margin="42,16,42,12">
|
||||
<ui:TextBlock Margin="0,0,0,8"
|
||||
FontTypography="BodyStrong"
|
||||
@@ -605,7 +605,7 @@
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</ui:CardExpander>
|
||||
|
||||
|
||||
<!--回血相关设置-->
|
||||
<ui:CardExpander Margin="0,0,0,12" ContentPadding="0">
|
||||
<ui:CardExpander.Icon>
|
||||
@@ -636,84 +636,86 @@
|
||||
<StackPanel>
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ui:TextBlock Grid.Row="0" Grid.Column="0"
|
||||
<ui:TextBlock Grid.Row="0" Grid.Column="0"
|
||||
Text="是否就近七天神像恢复血量"
|
||||
FontTypography="Body"/>
|
||||
FontTypography="Body" />
|
||||
<ui:TextBlock Grid.Row="1" Grid.Column="0"
|
||||
Text="启用后将自动选择最近的七天神像,忽略下方指定位置"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"/>
|
||||
<ui:ToggleSwitch Grid.Row="0" Grid.RowSpan="2" Grid.Column="1"
|
||||
IsChecked="{Binding Config.TpConfig.IsReviveInNearestStatueOfTheSeven}"/>
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}" />
|
||||
<ui:ToggleSwitch Grid.Row="0" Grid.RowSpan="2" Grid.Column="1" Margin="0,0,36,0"
|
||||
IsChecked="{Binding Config.TpConfig.IsReviveInNearestStatueOfTheSeven}" />
|
||||
</Grid>
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ui:TextBlock Grid.Row="0" Grid.Column="0"
|
||||
<ui:TextBlock Grid.Row="0" Grid.Column="0"
|
||||
Text="传送到七天神像之后是否需要移动后回血"
|
||||
FontTypography="Body"/>
|
||||
FontTypography="Body" />
|
||||
<ui:TextBlock Grid.Row="1" Grid.Column="0"
|
||||
Text="启用后将自动向七天神像方向移动"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"/>
|
||||
<ui:ToggleSwitch Grid.Row="0" Grid.RowSpan="2" Grid.Column="1"
|
||||
IsChecked="{Binding Config.TpConfig.ShouldMove}"/>
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}" />
|
||||
<ui:ToggleSwitch Grid.Row="0" Grid.RowSpan="2" Grid.Column="1" Margin="0,0,36,0"
|
||||
IsChecked="{Binding Config.TpConfig.ShouldMove}" />
|
||||
</Grid>
|
||||
<!-- 指定国家 -->
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ui:TextBlock Grid.Row="0" Grid.Column="0"
|
||||
<ui:TextBlock Grid.Row="0" Grid.Column="0"
|
||||
Text="七天神像国家"
|
||||
FontTypography="Body"/>
|
||||
FontTypography="Body" />
|
||||
<ui:TextBlock Grid.Row="1" Grid.Column="0"
|
||||
Text="选择七天神像所在国家"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"/>
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}" />
|
||||
<ComboBox Grid.Row="0" Grid.RowSpan="2" Grid.Column="1"
|
||||
ItemsSource="{Binding CountryList}"
|
||||
SelectedItem="{Binding SelectedCountry}"
|
||||
MinWidth="120"/>
|
||||
Margin="0,0,36,0"
|
||||
ItemsSource="{Binding CountryList}"
|
||||
SelectedItem="{Binding SelectedCountry}"
|
||||
MinWidth="120" />
|
||||
</Grid>
|
||||
|
||||
<!-- 指定区域 -->
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ui:TextBlock Grid.Row="0" Grid.Column="0"
|
||||
<ui:TextBlock Grid.Row="0" Grid.Column="0"
|
||||
Text="七天神像区域"
|
||||
FontTypography="Body"/>
|
||||
FontTypography="Body" />
|
||||
<ui:TextBlock Grid.Row="1" Grid.Column="0"
|
||||
Text="选择七天神像所在区域"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"/>
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}" />
|
||||
<ComboBox Grid.Row="0" Grid.RowSpan="2" Grid.Column="1"
|
||||
ItemsSource="{Binding Areas}"
|
||||
SelectedItem="{Binding SelectedArea}"
|
||||
MinWidth="120"/>
|
||||
Margin="0,0,36,0"
|
||||
ItemsSource="{Binding Areas}"
|
||||
SelectedItem="{Binding SelectedArea}"
|
||||
MinWidth="120" />
|
||||
</Grid>
|
||||
|
||||
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
@@ -773,7 +775,7 @@
|
||||
Command="{Binding ImportLocalScriptsRepoZipCommand}"
|
||||
Content="导入" />
|
||||
</Grid>
|
||||
|
||||
|
||||
</ui:CardControl.Header>
|
||||
</ui:CardControl>
|
||||
|
||||
@@ -800,16 +802,16 @@
|
||||
Text="使按键绑定设置对外部脚本生效"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:ToggleSwitch Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,36,0"
|
||||
IsChecked="{Binding Config.KeyBindingsConfig.GlobalKeyMappingEnabled}"/>
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,36,0"
|
||||
IsChecked="{Binding Config.KeyBindingsConfig.GlobalKeyMappingEnabled}" />
|
||||
</Grid>
|
||||
|
||||
</ui:CardControl.Header>
|
||||
</ui:CardControl>
|
||||
<!-- 其他设置 -->
|
||||
<ui:CardExpander Margin="0,0,0,12" ContentPadding="0" >
|
||||
<!-- 其他设置 -->
|
||||
<ui:CardExpander Margin="0,0,0,12" ContentPadding="0">
|
||||
<ui:CardExpander.Icon>
|
||||
<ui:FontIcon Glyph="" Style="{StaticResource FaFontIconStyle}" />
|
||||
</ui:CardExpander.Icon>
|
||||
@@ -861,7 +863,7 @@
|
||||
Margin="0,0,36,0"
|
||||
IsChecked="{Binding Config.OtherConfig.RestoreFocusOnLostEnabled, Mode=TwoWay}" />
|
||||
</Grid>
|
||||
|
||||
|
||||
</StackPanel>
|
||||
</ui:CardExpander>
|
||||
<ui:TextBlock Margin="0,0,0,8"
|
||||
@@ -977,7 +979,7 @@
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="Webhook相关设置"
|
||||
Text="Webhook 相关设置"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:ToggleSwitch Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
@@ -999,12 +1001,12 @@
|
||||
<ui:TextBlock Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
FontTypography="Body"
|
||||
Text="Webhook端点"
|
||||
Text="Webhook 端点"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="填写Webhook端点"
|
||||
Text="填写 Webhook 端点"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBox Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
@@ -1015,6 +1017,34 @@
|
||||
Text="{Binding Config.NotificationConfig.WebhookEndpoint, Mode=TwoWay}"
|
||||
TextWrapping="NoWrap" />
|
||||
</Grid>
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="3*" />
|
||||
<ColumnDefinition Width="2*" />
|
||||
</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:TextBox Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
MinWidth="180"
|
||||
MaxWidth="800"
|
||||
Margin="0,0,36,0"
|
||||
Text="{Binding Config.NotificationConfig.WebhookSendTo, Mode=TwoWay}"
|
||||
TextWrapping="NoWrap" />
|
||||
</Grid>
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
@@ -1036,18 +1066,11 @@
|
||||
TextWrapping="Wrap" />
|
||||
<ui:Button Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Grid.RowSpan="2"
|
||||
Margin="0,0,36,0"
|
||||
HorizontalAlignment="Right"
|
||||
Command="{Binding TestWebhookCommand}"
|
||||
Content="发送"
|
||||
IsEnabled="{Binding IsLoading, Converter={StaticResource InverseBooleanConverter}}" />
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,36,0"
|
||||
HorizontalAlignment="Right"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="{Binding WebhookStatus}"
|
||||
TextWrapping="Wrap" />
|
||||
Content="发送"/>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</ui:CardExpander>
|
||||
@@ -1373,7 +1396,7 @@
|
||||
Margin="0,0,36,0"
|
||||
Command="{Binding TestWebSocketNotificationCommand}"
|
||||
Content="发送" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</ui:CardExpander>
|
||||
<!-- Email通知 -->
|
||||
@@ -1453,7 +1476,7 @@
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="填写 SMTP 服务器端口"
|
||||
Text="填写 SMTP 服务器端口,一般为:587"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBox Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
@@ -1693,7 +1716,7 @@
|
||||
Text="{Binding Config.NotificationConfig.BarkApiEndpoint, Mode=TwoWay}"
|
||||
TextWrapping="NoWrap" />
|
||||
</Grid>
|
||||
|
||||
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
@@ -1711,8 +1734,9 @@
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="多个设备使用逗号、分号或空格分隔 (请使用英文输入法)"
|
||||
Text="多个设备使用英文逗号、分号或空格分隔"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<ui:TextBox Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
@@ -1720,9 +1744,9 @@
|
||||
MaxWidth="800"
|
||||
Margin="0,0,36,0"
|
||||
Text="{Binding Config.NotificationConfig.BarkDeviceKeys, Mode=TwoWay}"
|
||||
TextWrapping="NoWrap" />
|
||||
TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
|
||||
|
||||
<!-- 高级参数 -->
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
@@ -1741,18 +1765,22 @@
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="critical(重要)
active(默认)
timeSensitive(专注下也会提醒)
passive(通知但不提醒)"
|
||||
Text="修改推送级别"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBox Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
MinWidth="180"
|
||||
MaxWidth="800"
|
||||
Margin="0,0,36,0"
|
||||
Text="{Binding Config.NotificationConfig.BarkLevel, Mode=TwoWay}"
|
||||
TextWrapping="NoWrap" />
|
||||
<ComboBox Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
SelectedItem="{Binding Config.NotificationConfig.BarkLevel}"
|
||||
SelectedValuePath="Tag"
|
||||
Margin="0,0,36,0"
|
||||
MinWidth="120">
|
||||
<ComboBoxItem Content="passive(通知但不提醒)" Tag="passive" />
|
||||
<ComboBoxItem Content="critical(重要通知)" Tag="critical" />
|
||||
<ComboBoxItem Content="active(默认通知)" Tag="active" />
|
||||
<ComboBoxItem Content="sensitive(专注通知)" Tag="timeSensitive" />
|
||||
</ComboBox>
|
||||
</Grid>
|
||||
|
||||
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
@@ -1770,18 +1798,20 @@
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="例如: minuet, silence, bell"
|
||||
Text="选择通知声音"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBox Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
MinWidth="180"
|
||||
MaxWidth="800"
|
||||
Margin="0,0,36,0"
|
||||
Text="{Binding Config.NotificationConfig.BarkSound, Mode=TwoWay}"
|
||||
TextWrapping="NoWrap" />
|
||||
<ComboBox Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
SelectedItem="{Binding Config.NotificationConfig.BarkSound}"
|
||||
Margin="0,0,36,0"
|
||||
MinWidth="120">
|
||||
<ComboBoxItem Content="minuet" />
|
||||
<ComboBoxItem Content="silence" />
|
||||
<ComboBoxItem Content="bell" />
|
||||
</ComboBox>
|
||||
</Grid>
|
||||
|
||||
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
@@ -1810,7 +1840,7 @@
|
||||
Text="{Binding Config.NotificationConfig.BarkGroup, Mode=TwoWay}"
|
||||
TextWrapping="NoWrap" />
|
||||
</Grid>
|
||||
|
||||
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
@@ -1828,16 +1858,19 @@
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="传1保存推送,传其他不保存"
|
||||
Text="选择是否保存推送历史"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBox Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
MinWidth="180"
|
||||
MaxWidth="800"
|
||||
Margin="0,0,36,0"
|
||||
Text="{Binding Config.NotificationConfig.BarkIsArchive, Mode=TwoWay}"
|
||||
TextWrapping="NoWrap" />
|
||||
<ComboBox Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
MinWidth="180"
|
||||
MaxWidth="800"
|
||||
Margin="0,0,36,0"
|
||||
SelectedValue="{Binding Config.NotificationConfig.BarkIsArchive, Mode=TwoWay}"
|
||||
SelectedValuePath="Tag">
|
||||
<ComboBoxItem Content="是" Tag="1" />
|
||||
<ComboBoxItem Content="否" Tag="0" />
|
||||
</ComboBox>
|
||||
</Grid>
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
@@ -1896,6 +1929,154 @@
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</ui:CardExpander>
|
||||
<!-- Telegram通知 -->
|
||||
<ui:CardExpander Margin="0,0,0,12"
|
||||
ContentPadding="0"
|
||||
Icon="{ui:SymbolIcon Send20}">
|
||||
<ui:CardExpander.Header>
|
||||
<Grid>
|
||||
<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="启用 Telegram 通知"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="Telegram 机器人相关设置"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:ToggleSwitch Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,24,0"
|
||||
IsChecked="{Binding Config.NotificationConfig.TelegramNotificationEnabled, Mode=TwoWay}" />
|
||||
</Grid>
|
||||
</ui:CardExpander.Header>
|
||||
<StackPanel>
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="3*" />
|
||||
<ColumnDefinition Width="2*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ui:TextBlock Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
FontTypography="Body"
|
||||
Text="机器人 Token"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="填写 Telegram 机器人的 Token"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBox Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
MinWidth="180"
|
||||
MaxWidth="800"
|
||||
Margin="0,0,36,0"
|
||||
Text="{Binding Config.NotificationConfig.TelegramBotToken, Mode=TwoWay}"
|
||||
TextWrapping="NoWrap" />
|
||||
</Grid>
|
||||
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="3*" />
|
||||
<ColumnDefinition Width="2*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ui:TextBlock Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
FontTypography="Body"
|
||||
Text="聊天 ID"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="填写接收消息的聊天 ID"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBox Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
MinWidth="180"
|
||||
MaxWidth="800"
|
||||
Margin="0,0,36,0"
|
||||
Text="{Binding Config.NotificationConfig.TelegramChatId, Mode=TwoWay}"
|
||||
TextWrapping="NoWrap" />
|
||||
</Grid>
|
||||
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="3*" />
|
||||
<ColumnDefinition Width="2*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ui:TextBlock Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
FontTypography="Body"
|
||||
Text="API 基础 URL(可选)"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="留空使用官方 API,或填写第三方 API 地址"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBox Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
MinWidth="180"
|
||||
MaxWidth="800"
|
||||
Margin="0,0,36,0"
|
||||
Text="{Binding Config.NotificationConfig.TelegramApiBaseUrl, Mode=TwoWay}"
|
||||
TextWrapping="NoWrap" />
|
||||
</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="测试 Telegram 通知"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="发送测试通知"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:Button Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,36,0"
|
||||
Command="{Binding TestTelegramNotificationCommand}"
|
||||
Content="发送" />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</ui:CardExpander>
|
||||
<!-- 地图 -->
|
||||
<!--<ui:CardControl Margin="0,0,0,12"
|
||||
Icon="{ui:SymbolIcon Cursor24}"
|
||||
@@ -1950,4 +2131,4 @@
|
||||
IsChecked="{Binding Config.MaskWindowConfig.ShowLogBox, Mode=TwoWay}"/>
|
||||
</ui:CardControl>-->
|
||||
</StackPanel>
|
||||
</Page>
|
||||
</Page>
|
||||
@@ -33,13 +33,6 @@ public partial class CommonSettingsPageViewModel : ViewModel
|
||||
private readonly INavigationService _navigationService;
|
||||
|
||||
private readonly NotificationService _notificationService;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isLoading;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _webhookStatus = string.Empty;
|
||||
|
||||
public ObservableCollection<string> CountryList { get; } = new();
|
||||
public ObservableCollection<string> Areas { get; } = new();
|
||||
private readonly TpConfig _tpConfig = TaskContext.Instance().Config.TpConfig;
|
||||
@@ -192,14 +185,15 @@ public partial class CommonSettingsPageViewModel : ViewModel
|
||||
[RelayCommand]
|
||||
private async Task OnTestWebhook()
|
||||
{
|
||||
IsLoading = true;
|
||||
WebhookStatus = string.Empty;
|
||||
|
||||
var res = await _notificationService.TestNotifierAsync<WebhookNotifier>();
|
||||
|
||||
WebhookStatus = res.Message;
|
||||
|
||||
IsLoading = false;
|
||||
if(res.IsSuccess)
|
||||
{
|
||||
Toast.Success(res.Message);
|
||||
}
|
||||
else
|
||||
{
|
||||
Toast.Error(res.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
@@ -286,6 +280,21 @@ public partial class CommonSettingsPageViewModel : ViewModel
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task OnTestTelegramNotification()
|
||||
{
|
||||
var res = await _notificationService.TestNotifierAsync<TelegramNotifier>();
|
||||
if(res.IsSuccess)
|
||||
{
|
||||
Toast.Success(res.Message);
|
||||
}
|
||||
else
|
||||
{
|
||||
Toast.Error(res.Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[RelayCommand]
|
||||
private void ImportLocalScriptsRepoZip()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user