mirror of
https://github.com/babalae/better-genshin-impact.git
synced 2026-03-15 07:43:20 +08:00
182 lines
7.0 KiB
C#
182 lines
7.0 KiB
C#
using BetterGenshinImpact.Core.Config;
|
|
using BetterGenshinImpact.GameTask.AutoPathing.Model;
|
|
using BetterGenshinImpact.GameTask.AutoPathing.Model.Enum;
|
|
using BetterGenshinImpact.GameTask.Common;
|
|
using BetterGenshinImpact.GameTask.Common.Map;
|
|
using BetterGenshinImpact.View.Controls.Webview;
|
|
using BetterGenshinImpact.ViewModel.Pages;
|
|
using Microsoft.Extensions.Logging;
|
|
using System;
|
|
using System.IO;
|
|
using System.Text.Json;
|
|
using System.Text.Json.Serialization;
|
|
using System.Windows;
|
|
using BetterGenshinImpact.Core.Script.WebView;
|
|
using BetterGenshinImpact.GameTask.Common.Map.Maps;
|
|
using BetterGenshinImpact.GameTask.Common.Map.Maps.Base;
|
|
using BetterGenshinImpact.Helpers;
|
|
using BetterGenshinImpact.Model;
|
|
using Microsoft.Web.WebView2.Core;
|
|
|
|
namespace BetterGenshinImpact.GameTask.AutoPathing;
|
|
|
|
public class PathRecorder : Singleton<PathRecorder>
|
|
{
|
|
private WebpageWindow? _webWindow;
|
|
|
|
public static readonly JsonSerializerOptions JsonOptions = new()
|
|
{
|
|
NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals,
|
|
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
|
|
PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower, // 下划线
|
|
AllowTrailingCommas = true,
|
|
ReadCommentHandling = JsonCommentHandling.Skip,
|
|
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
|
|
};
|
|
|
|
private PathingTask _pathingTask = new();
|
|
|
|
|
|
private string GetMapName()
|
|
{
|
|
var mapName = TaskContext.Instance().Config.DevConfig.RecordMapName;
|
|
if (string.IsNullOrEmpty(mapName))
|
|
{
|
|
mapName = nameof(MapTypes.Teyvat);
|
|
}
|
|
|
|
return mapName;
|
|
}
|
|
|
|
public void Start()
|
|
{
|
|
var matchingMethod = TaskContext.Instance().Config.PathingConditionConfig.MapMatchingMethod;
|
|
Navigation.WarmUp(matchingMethod);
|
|
_pathingTask = new PathingTask();
|
|
TaskControl.Logger.LogInformation("开始路径点记录");
|
|
if (GetMapName() == nameof(MapTypes.Teyvat))
|
|
{
|
|
TaskControl.Logger.LogInformation("如果需要切换其他地图,请在 {Msg} 中切换", "地图追踪——开发者工具");
|
|
}
|
|
|
|
var waypoint = new Waypoint();
|
|
var screen = TaskControl.CaptureToRectArea();
|
|
var position = Navigation.GetPositionStable(screen, GetMapName(), matchingMethod);
|
|
var nullablePosition = MapManager.GetMap(GetMapName(), matchingMethod).ConvertImageCoordinatesToGenshinMapCoordinates(position);
|
|
if (nullablePosition == null)
|
|
{
|
|
TaskControl.Logger.LogWarning("未识别到当前位置!");
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
position = nullablePosition.Value;
|
|
}
|
|
waypoint.X = position.X;
|
|
waypoint.Y = position.Y;
|
|
waypoint.Type = WaypointType.Teleport.Code;
|
|
waypoint.MoveMode = MoveModeEnum.Walk.Code;
|
|
_pathingTask.Positions.Add(waypoint);
|
|
if (_webWindow == null)
|
|
{
|
|
TaskControl.Logger.LogInformation("已创建初始路径点({x},{y})", waypoint.X, waypoint.Y);
|
|
}
|
|
else
|
|
{
|
|
TaskControl.Logger.LogInformation("已添加途径点({x},{y})", waypoint.X, waypoint.Y);
|
|
AddPosToEditor(waypoint.X, waypoint.Y);
|
|
}
|
|
}
|
|
|
|
public void AddWaypoint(string waypointType = "")
|
|
{
|
|
Waypoint waypoint = new();
|
|
var screen = TaskControl.CaptureToRectArea();
|
|
var matchingMethod = TaskContext.Instance().Config.PathingConditionConfig.MapMatchingMethod;
|
|
var position = Navigation.GetPositionStable(screen, GetMapName(), matchingMethod);
|
|
var nullablePosition = MapManager.GetMap(GetMapName(), matchingMethod).ConvertImageCoordinatesToGenshinMapCoordinates(position);
|
|
if (nullablePosition == null)
|
|
{
|
|
TaskControl.Logger.LogWarning("未识别到当前位置!");
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
position = nullablePosition.Value;
|
|
}
|
|
|
|
waypoint.X = position.X;
|
|
waypoint.Y = position.Y;
|
|
waypoint.Type = string.IsNullOrEmpty(waypointType) ? WaypointType.Path.Code : waypointType;
|
|
_pathingTask.Positions.Add(waypoint);
|
|
TaskControl.Logger.LogInformation("已添加途径点({x},{y})", waypoint.X, waypoint.Y);
|
|
AddPosToEditor(waypoint.X, waypoint.Y);
|
|
}
|
|
|
|
public void Save()
|
|
{
|
|
if (_webWindow == null)
|
|
{
|
|
var matchingMethod = TaskContext.Instance().Config.PathingConditionConfig.MapMatchingMethod;
|
|
_pathingTask.Info = new PathingTaskInfo
|
|
{
|
|
Name = "未命名路线",
|
|
Type = PathingTaskType.Collect.Code,
|
|
MapName = GetMapName(),
|
|
MapMatchMethod = matchingMethod,
|
|
BgiVersion = Global.Version
|
|
};
|
|
var name = $@"{DateTime.Now:yyyyMMdd_HHmmss}.json";
|
|
_pathingTask.SaveToFile(Path.Combine(MapPathingViewModel.PathJsonPath, name));
|
|
TaskControl.Logger.LogInformation("录制编辑器未打开,直接保存路径点记录:{Name}", name);
|
|
}
|
|
else
|
|
{
|
|
TaskControl.Logger.LogInformation("路径点记录结束,请在录制编辑器中查看并编辑结果");
|
|
TaskControl.Logger.LogInformation("如果要重新录制新的路径,请在录制编辑器中删除已有路径或创建新的路径");
|
|
TaskControl.Logger.LogInformation("修改完毕后请务必记得导出路径!");
|
|
}
|
|
}
|
|
|
|
private void AddPosToEditor(double x, double y)
|
|
{
|
|
if (_webWindow != null)
|
|
{
|
|
UIDispatcherHelper.Invoke(() => { _webWindow.WebView.ExecuteScriptAsync($"addNewPoint({x},{y})"); });
|
|
}
|
|
}
|
|
|
|
public void OpenEditorInWebView(string mapName = "Teyvat")
|
|
{
|
|
if (_webWindow is not { IsVisible: true })
|
|
{
|
|
_webWindow = new WebpageWindow
|
|
{
|
|
Title = "地图路径点编辑器",
|
|
Width = 1366,
|
|
Height = 768,
|
|
// Owner = Application.Current.MainWindow,
|
|
WindowState = WindowState.Maximized
|
|
};
|
|
_webWindow.Closed += (s, e) => _webWindow = null;
|
|
_webWindow.Panel!.DownloadFolderPath = MapPathingViewModel.PathJsonPath;
|
|
|
|
var htmlPath = Global.Absolute(@"Assets\Map\Editor\index.html");
|
|
var uri = new UriBuilder(htmlPath);
|
|
var query = System.Web.HttpUtility.ParseQueryString(string.Empty);
|
|
query["map"] = mapName;
|
|
uri.Query = query.ToString();
|
|
_webWindow.NavigateToFile(uri.ToString());
|
|
_webWindow.Panel!.OnWebViewInitializedAction = () =>
|
|
{
|
|
_webWindow.Panel!.WebView.CoreWebView2.AddHostObjectToScript("mapEditorWebBridge", new MapEditorWebBridge());
|
|
_webWindow.Panel!.WebView.CoreWebView2.AddHostObjectToScript("fileAccessBridge", new FileAccessBridge(Global.Absolute("User/AutoPathing")));
|
|
};
|
|
_webWindow.Show();
|
|
}
|
|
else
|
|
{
|
|
_webWindow.Activate();
|
|
}
|
|
}
|
|
} |