mirror of
https://github.com/babalae/better-genshin-impact.git
synced 2026-05-09 00:34:14 +08:00
feat: 支持在脚本中进行http请求 (#2331)
This commit is contained in:
84
BetterGenshinImpact/Core/Script/Dependence/Http.cs
Normal file
84
BetterGenshinImpact/Core/Script/Dependence/Http.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
|
||||
// 任务调度器
|
||||
|
||||
@@ -106,6 +106,10 @@ public partial class ScriptGroupProject : ObservableObject
|
||||
[ObservableProperty]
|
||||
private bool? _allowJsNotification = true;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool? _allowJsHTTP = false;
|
||||
|
||||
|
||||
public ScriptGroupProject()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user