feat: 支持在脚本中进行http请求 (#2331)

This commit is contained in:
NyaMisty
2025-10-13 00:42:20 +08:00
committed by GitHub
parent 38a5ddc842
commit 910b005461
6 changed files with 112 additions and 0 deletions

View File

@@ -0,0 +1,84 @@
using BetterGenshinImpact.Core.Script.Utils;
using System;
using System.IO;
using System.Threading.Tasks;
using OpenCvSharp;
using System.Linq;
using System.Text.Json;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using BetterGenshinImpact.GameTask;
namespace BetterGenshinImpact.Core.Script.Dependence;
public class Http
{
private bool CheckHttpPermission()
{
try
{
var currentProject = TaskContext.Instance().CurrentScriptProject;
return currentProject?.AllowJsHTTP ?? false;
}
catch
{
return false;
}
}
/// <summary>
/// 执行HTTP请求
/// </summary>
/// <param name="method">HTTP方法</param>
/// <param name="url">请求URL</param>
/// <param name="body">请求体</param
/// <returns></returns>
public async Task<string> Request(string method, string url, string? body, string? headersJson)
{
if (!CheckHttpPermission())
{
throw new UnauthorizedAccessException("当前JS脚本不允许使用HTTP请求请在调度器通用设置中启用“JS HTTP权限”");
}
var dictHeaders = new Dictionary<string, string>();
if (!string.IsNullOrWhiteSpace(headersJson))
{
try
{
var headers = JsonSerializer.Deserialize<Dictionary<string, string>>(headersJson);
if (headers != null)
{
dictHeaders = headers;
}
}
catch (JsonException)
{
throw new ArgumentException("Headers JSON格式错误");
}
}
// header全部小写
dictHeaders = dictHeaders.ToDictionary(kvp => kvp.Key.ToLowerInvariant(), kvp => kvp.Value);
// 提前取出来Content-Type防止被覆盖
string contentType = "application/json";
if (dictHeaders.TryGetValue("content-type", out var ct))
{
contentType = ct;
dictHeaders.Remove("content-type");
}
// 使用HttpClient发送请求
using var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Clear();
foreach (var header in dictHeaders)
{
httpClient.DefaultRequestHeaders.Add(header.Key, header.Value);
}
var content = body == null ? null : new StringContent(body, Encoding.UTF8, contentType);
var response = await httpClient.SendAsync(new HttpRequestMessage(new HttpMethod(method), url) { Content = content });
return await response.Content.ReadAsStringAsync();
}
}

View File

@@ -32,6 +32,7 @@ public class EngineExtend
engine.AddHostObject("genshin", new Dependence.Genshin());
engine.AddHostObject("log", new Log());
engine.AddHostObject("file", new LimitedFile(workDir)); // 限制文件访问
engine.AddHostObject("http", new Http()); // 限制文件访问
engine.AddHostObject("notification", new Notification());
// 任务调度器

View File

@@ -106,6 +106,10 @@ public partial class ScriptGroupProject : ObservableObject
[ObservableProperty]
private bool? _allowJsNotification = true;
[ObservableProperty]
private bool? _allowJsHTTP = false;
public ScriptGroupProject()
{
}

View File

@@ -486,6 +486,7 @@ public partial class ScriptService : IScriptService
target.JsScriptSettingsObject = source.JsScriptSettingsObject;
target.GroupInfo = source.GroupInfo;
target.AllowJsNotification = source.AllowJsNotification;
target.AllowJsHTTP = source.AllowJsHTTP;
target.SkipFlag = source.SkipFlag;
}

View File

@@ -49,6 +49,14 @@
SelectedValue="{Binding AllowJsNotification, Mode=TwoWay}"
Visibility="{Binding IsJsScript, Converter={StaticResource BoolToVisConverter}}">
</ComboBox>
<TextBlock Margin="0,10,0,5" Text="JS HTTP权限"
Visibility="{Binding IsJsScript, Converter={StaticResource BoolToVisConverter}}"/>
<ComboBox DisplayMemberPath="Value"
ItemsSource="{Binding JsNotificationOptions}"
SelectedValue="{Binding AllowJsHTTP, Mode=TwoWay}"
SelectedValuePath="Key"
Visibility="{Binding IsJsScript, Converter={StaticResource BoolToVisConverter}}">
</ComboBox>
</StackPanel>
</Grid>

View File

@@ -35,6 +35,16 @@ public class ScriptGroupProjectEditorViewModel : ObservableObject
}
}
public bool? AllowJsHTTP
{
get => _project.AllowJsHTTP;
set
{
_project.AllowJsHTTP = value;
OnPropertyChanged();
}
}
public string Status
{
get => _project.Status;
@@ -58,6 +68,10 @@ public class ScriptGroupProjectEditorViewModel : ObservableObject
{
OnPropertyChanged(nameof(AllowJsNotification));
}
if (e.PropertyName == nameof(ScriptGroupProject.AllowJsHTTP))
{
OnPropertyChanged(nameof(AllowJsHTTP));
}
};
}
}