mirror of
https://github.com/k1tbyte/Wand-Enhancer.git
synced 2026-08-29 01:08:51 +00:00
refactor: rebrand project to WandEnhancer
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
namespace WandEnhancer.View.MainWindow
|
||||
{
|
||||
public enum ELogType
|
||||
{
|
||||
Info,
|
||||
Warn,
|
||||
Error,
|
||||
Success
|
||||
}
|
||||
public class LogEntry
|
||||
{
|
||||
public ELogType LogType { get; set; }
|
||||
public string Message { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
<Window x:Class="WandEnhancer.View.MainWindow.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:WandEnhancer.View.MainWindow"
|
||||
xmlns:controls="clr-namespace:WandEnhancer.View.Controls"
|
||||
mc:Ignorable="d"
|
||||
d:DataContext="{d:DesignInstance local:MainWindowVm}"
|
||||
Title="WandEnhancer"
|
||||
Height="510" MaxHeight="510"
|
||||
Width="780" MaxWidth="780"
|
||||
Opacity="0.97"
|
||||
Background="Transparent"
|
||||
WindowStyle="None"
|
||||
FontFamily="{StaticResource Inter}"
|
||||
AllowsTransparency="True">
|
||||
<Border CornerRadius="7" Background="{DynamicResource Background}"
|
||||
BorderBrush="{DynamicResource Border}"
|
||||
BorderThickness="1" Margin="10">
|
||||
<Border.Effect>
|
||||
<DropShadowEffect BlurRadius="15" Direction="-90"
|
||||
RenderingBias="Quality" ShadowDepth="2"/>
|
||||
</Border.Effect>
|
||||
|
||||
<Grid>
|
||||
<Grid Background="Transparent" VerticalAlignment="Top"
|
||||
MouseLeftButtonDown="OnDragMove" Height="55">
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" Margin="25 0 0 0">
|
||||
<Viewbox VerticalAlignment="Center" Width="32" Height="32">
|
||||
<Path
|
||||
Fill="White" Data="{StaticResource Logo}"/>
|
||||
</Viewbox>
|
||||
<TextBlock Foreground="{DynamicResource Foreground}"
|
||||
FontWeight="SemiBold" Opacity="0.9"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="18" Margin="10 0 0 0">
|
||||
<Bold>
|
||||
WandEnhancer
|
||||
</Bold>
|
||||
</TextBlock>
|
||||
<TextBlock x:Name="VersionLabel" VerticalAlignment="Bottom"
|
||||
Opacity="0.7" FontSize="10" Margin="5 0 0 5"
|
||||
Foreground="{DynamicResource Foreground}">
|
||||
v 1.0.0
|
||||
</TextBlock>
|
||||
|
||||
<Button Background="SpringGreen" Foreground="{DynamicResource Muted}"
|
||||
FontWeight="Medium" Padding="20 0" Margin="10 5 20 5"
|
||||
ToolTip="Click to update"
|
||||
Command="{Binding UpdateCommand}"
|
||||
Visibility="{Binding IsUpdateAvailable, Converter={StaticResource ToVisibilityConverter}}"
|
||||
Content="{DynamicResource mw_update_available}"/>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
|
||||
<Button
|
||||
Margin="0 0 5 0"
|
||||
Width="25" Height="25" Padding="5.5"
|
||||
Style="{StaticResource IconButton}"
|
||||
Tag="{StaticResource CogIcon}"
|
||||
Command="{Binding OpenSettingsCommand}"
|
||||
/>
|
||||
<Button
|
||||
Margin="9 0 15 0"
|
||||
Tag="{StaticResource CloseIcon}"
|
||||
Width="25" Height="25" Padding="6.5"
|
||||
HorizontalAlignment="Right"
|
||||
Click="OnClosing"
|
||||
VerticalAlignment="Center">
|
||||
<Button.Resources>
|
||||
<CornerRadius x:Key="CornerRadius">5 5 5 5</CornerRadius>
|
||||
</Button.Resources>
|
||||
<Button.Style>
|
||||
<Style BasedOn="{StaticResource IconButton}" TargetType="Button">
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Background" Value="{DynamicResource Secondary}"/>
|
||||
<Setter Property="Foreground" Value="{DynamicResource Destructive}"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Button.Style>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
|
||||
<Border Background="{DynamicResource Border}" Height="1" VerticalAlignment="Bottom"></Border>
|
||||
|
||||
</Grid>
|
||||
<Grid Margin="0 55 0 0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition/>
|
||||
<RowDefinition Height="50"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid Margin="10" Cursor="Hand" Background="Transparent">
|
||||
<TextBox Style="{StaticResource TitledTextBox}"
|
||||
IsReadOnly="True"
|
||||
Text="{Binding WeModInfo.RootDirectory, Mode=OneWay}"
|
||||
VerticalAlignment="Center">
|
||||
</TextBox>
|
||||
<Grid.InputBindings>
|
||||
<MouseBinding Gesture="LeftClick" Command="{Binding SetFolderPathCommand}" />
|
||||
</Grid.InputBindings>
|
||||
</Grid>
|
||||
|
||||
|
||||
<Border Grid.Row="1" BorderBrush="{DynamicResource Border}" BorderThickness="1"
|
||||
Margin="10 0 10 10"
|
||||
CornerRadius="5">
|
||||
<ListBox ItemsSource="{Binding LogList}" SelectionMode="Single"
|
||||
BorderBrush="Transparent" BorderThickness="0"
|
||||
Background="Transparent"
|
||||
x:Name="LogList"
|
||||
Padding="6"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Hidden"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
||||
ScrollViewer.CanContentScroll="False">
|
||||
<ListBox.ItemContainerStyle>
|
||||
<Style TargetType="ListBoxItem">
|
||||
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
|
||||
<Setter Property="Margin" Value="0 0 0 5"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ListBoxItem">
|
||||
<Border x:Name="Card" HorizontalAlignment="Left"
|
||||
Background="#08fc81"
|
||||
BorderBrush="{DynamicResource Border}"
|
||||
Padding="5 3 5 3" CornerRadius="3">
|
||||
<TextBox Text="{Binding Message}"
|
||||
Cursor="IBeam" FontSize="13"
|
||||
Background="Transparent" TextWrapping="Wrap"
|
||||
BorderThickness="0"
|
||||
IsReadOnly="True"/>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<DataTrigger Binding="{Binding LogType}" Value="Error">
|
||||
<Setter TargetName="Card" Property="Background" Value="#f04343"></Setter>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding LogType}" Value="Info">
|
||||
<Setter TargetName="Card" Property="Background" Value="#FFF"></Setter>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding LogType}" Value="Warn">
|
||||
<Setter TargetName="Card" Property="Background" Value="#facc15"></Setter>
|
||||
</DataTrigger>
|
||||
</ControlTemplate.Triggers>
|
||||
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</ListBox.ItemContainerStyle>
|
||||
</ListBox>
|
||||
</Border>
|
||||
|
||||
|
||||
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal" Grid.Row="2" Margin="10 0 10 10">
|
||||
<Grid>
|
||||
<Grid HorizontalAlignment="Right" >
|
||||
<Grid.Style>
|
||||
<Style TargetType="{x:Type Grid}">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsPatchEnabled}" Value="False">
|
||||
<Setter Property="Cursor" Value="No"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Grid.Style>
|
||||
<Button Style="{StaticResource ColoredButton}"
|
||||
IsEnabled="{Binding IsPatchEnabled}"
|
||||
FontWeight="Bold" FontSize="16" Width="200"
|
||||
Command="{Binding ApplyPatchCommand}"
|
||||
Content="{DynamicResource mw_patch}"/>
|
||||
</Grid>
|
||||
<Button HorizontalAlignment="Right"
|
||||
Command="{Binding RestoreBackupCommand }"
|
||||
FontWeight="Bold" FontSize="16" Width="200"
|
||||
Style="{StaticResource ColoredButton}"
|
||||
Visibility="{Binding AlreadyPatched, Converter={StaticResource ToVisibilityConverter}}"
|
||||
Content="{DynamicResource mw_restore}"/>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
|
||||
|
||||
|
||||
<DockPanel Grid.Row="2" Margin="10 0 10 10">
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center"
|
||||
Cursor="Hand"
|
||||
HorizontalAlignment="Left"
|
||||
MouseDown="OpenSourceClicked"
|
||||
Background="Transparent">
|
||||
<Viewbox VerticalAlignment="Center" Width="32" Height="32">
|
||||
<Path
|
||||
Fill="White" Data="{StaticResource GitHub}"/>
|
||||
</Viewbox>
|
||||
<Grid>
|
||||
<TextBlock Margin="8 0 0 0" FontSize="10" Foreground="{DynamicResource AccentForeground}">
|
||||
<Hyperlink Foreground="{DynamicResource AccentForeground}"><Run Text="{DynamicResource mw_source_code}"/></Hyperlink>
|
||||
<LineBreak/>
|
||||
<Run Text="{DynamicResource mw_made_by}"/>
|
||||
|
||||
|
||||
<LineBreak/>
|
||||
<Run Foreground="{DynamicResource MutedForeground}" Text="{DynamicResource mw_star_hint}"/>
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</DockPanel>
|
||||
</Grid>
|
||||
|
||||
<controls:PopupHost x:Name="PopupHost"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Window>
|
||||
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace WandEnhancer.View.MainWindow
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for MainWindow.xaml
|
||||
/// </summary>
|
||||
public partial class MainWindow
|
||||
{
|
||||
public static MainWindow Instance;
|
||||
public readonly MainWindowVm ViewModel;
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.ViewModel = new MainWindowVm(this);
|
||||
this.DataContext = ViewModel;
|
||||
VersionLabel.Text = Constants.Version.ToString();
|
||||
Instance = this;
|
||||
|
||||
}
|
||||
|
||||
public void OpenPopup(FrameworkElement content, string title = null)
|
||||
{
|
||||
this.PopupHost.PopupContent = content;
|
||||
PopupHost.Title.Text = title;
|
||||
PopupHost.IsOpen = true;
|
||||
}
|
||||
|
||||
private void OnDragMove(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
this.DragMove();
|
||||
}
|
||||
|
||||
private void OnClosing(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Application.Current.Shutdown();
|
||||
}
|
||||
|
||||
public void ClosePopup()
|
||||
{
|
||||
PopupHost.IsOpen = false;
|
||||
}
|
||||
|
||||
private void OpenSourceClicked(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
System.Diagnostics.Process.Start(Constants.RepositoryUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,228 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using WandEnhancer.Core;
|
||||
using WandEnhancer.Models;
|
||||
using WandEnhancer.ReactiveUICore;
|
||||
using WandEnhancer.Utils;
|
||||
using WandEnhancer.View.Popups;
|
||||
using Application = System.Windows.Application;
|
||||
|
||||
namespace WandEnhancer.View.MainWindow
|
||||
{
|
||||
public class MainWindowVm : ObservableObject
|
||||
{
|
||||
private readonly MainWindow _view;
|
||||
public ObservableCollection<LogEntry> LogList { get; set; } = new ObservableCollection<LogEntry>();
|
||||
private static Updater _updater = new Updater();
|
||||
|
||||
private WeModConfig _weModConfig;
|
||||
|
||||
public WeModConfig WeModInfo
|
||||
{
|
||||
get => _weModConfig;
|
||||
set
|
||||
{
|
||||
SetProperty(ref _weModConfig, value);
|
||||
if (value == null) return;
|
||||
|
||||
Log($"WeMod directory found at '{_weModConfig}' ({_weModConfig.ExecutableName})", ELogType.Success);
|
||||
if (File.Exists(Path.Combine(_weModConfig.RootDirectory, "resources", "app.asar.backup")))
|
||||
{
|
||||
Log("WeMod already patched. If you want to patch again, please restore the backup first.",
|
||||
ELogType.Warn);
|
||||
IsPatchEnabled = false;
|
||||
AlreadyPatched = true;
|
||||
return;
|
||||
}
|
||||
|
||||
Log("Ready for patching.", ELogType.Info);
|
||||
IsPatchEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isPatchEnabled;
|
||||
|
||||
public bool IsPatchEnabled
|
||||
{
|
||||
get => _isPatchEnabled;
|
||||
set => SetProperty(ref _isPatchEnabled, value);
|
||||
}
|
||||
|
||||
private bool _alreadyPatched;
|
||||
|
||||
public bool AlreadyPatched
|
||||
{
|
||||
get => _alreadyPatched;
|
||||
set => SetProperty(ref _alreadyPatched, value);
|
||||
}
|
||||
|
||||
private bool _isUpdateAvailable;
|
||||
|
||||
public bool IsUpdateAvailable
|
||||
{
|
||||
get => _isUpdateAvailable;
|
||||
set => SetProperty(ref _isUpdateAvailable, value);
|
||||
}
|
||||
|
||||
public RelayCommand SetFolderPathCommand { get; }
|
||||
public RelayCommand ApplyPatchCommand { get; }
|
||||
public RelayCommand RestoreBackupCommand { get; }
|
||||
public RelayCommand UpdateCommand { get; }
|
||||
public RelayCommand OpenSettingsCommand { get; }
|
||||
|
||||
private void OnFolderPathSelection(object obj)
|
||||
{
|
||||
using (var dialog = new FolderBrowserDialog())
|
||||
{
|
||||
dialog.SelectedPath = Environment.GetEnvironmentVariable("LOCALAPPDATA");
|
||||
dialog.Description = "Select the WeMod directory";
|
||||
dialog.ShowNewFolderButton = false;
|
||||
|
||||
if (dialog.ShowDialog() != DialogResult.OK) return;
|
||||
string selectedPath = dialog.SelectedPath;
|
||||
string fileName = Path.GetFileName(selectedPath);
|
||||
|
||||
var info = Extensions.CheckWeModPath(selectedPath);
|
||||
|
||||
if (info != null)
|
||||
{
|
||||
WeModInfo = info;
|
||||
return;
|
||||
}
|
||||
|
||||
LogList.Add(new LogEntry
|
||||
{
|
||||
LogType = ELogType.Error,
|
||||
Message = $"The selected folder '{fileName}' is not a valid WeMod directory."
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void OnBackupRestoring(object param)
|
||||
{
|
||||
var backupPath = Path.Combine(WeModInfo.RootDirectory, "resources", "app.asar.backup");
|
||||
if (!File.Exists(backupPath))
|
||||
{
|
||||
Log("Backup not found. Please dont delete it manually", ELogType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Try to lock the file to see if it's in use
|
||||
using (File.Open(backupPath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
|
||||
{
|
||||
}
|
||||
|
||||
var proxyDllPath = Path.Combine(WeModInfo.RootDirectory, "version.dll");
|
||||
|
||||
if(File.Exists(proxyDllPath))
|
||||
{
|
||||
File.Delete(proxyDllPath);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
Log("Backup file is locked. Please close the WeMod and try again.", ELogType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
File.Copy(backupPath, Path.Combine(WeModInfo.RootDirectory, "resources", "app.asar"), true);
|
||||
File.Delete(backupPath);
|
||||
Log("Backup restored successfully.", ELogType.Success);
|
||||
AlreadyPatched = false;
|
||||
IsPatchEnabled = true;
|
||||
}
|
||||
|
||||
private void OnPatching(object param)
|
||||
{
|
||||
if (WeModInfo == null)
|
||||
{
|
||||
Log("Can't be done. Please specify the directory first.", ELogType.Warn);
|
||||
return;
|
||||
}
|
||||
|
||||
MainWindow.Instance.OpenPopup(new PatchVectorsPopup(async config =>
|
||||
{
|
||||
MainWindow.Instance.ClosePopup();
|
||||
IsPatchEnabled = false;
|
||||
await Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
new Enhancer(WeModInfo, Log, config).Patch();
|
||||
AlreadyPatched = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log($"Failed to patch: {e.Message}", ELogType.Error);
|
||||
IsPatchEnabled = true;
|
||||
}
|
||||
});
|
||||
}), Application.Current.FindResource("pv_popup_title") as string);
|
||||
}
|
||||
|
||||
private void Log(string message, ELogType logType)
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
message = $"[{logType.ToString().ToUpper()}] {message}";
|
||||
|
||||
var entry = new LogEntry
|
||||
{
|
||||
LogType = logType,
|
||||
Message = message
|
||||
};
|
||||
LogList.Add(entry);
|
||||
_view.LogList.ScrollIntoView(entry);
|
||||
});
|
||||
}
|
||||
|
||||
private void OnUpdate(object param)
|
||||
{
|
||||
MainWindow.Instance.OpenPopup(new UpdatePopup(() =>
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await _updater.Update();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log($"Failed to update: {e.Message}", ELogType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
Log("WandEnhancer updated successfully. Restarting...", ELogType.Success);
|
||||
});
|
||||
}), Application.Current.FindResource("up_popup_title") as string);
|
||||
}
|
||||
|
||||
private void OnOpenSettings(object param)
|
||||
{
|
||||
MainWindow.Instance.OpenPopup(new SettingsPopup(), Application.Current.FindResource("settings_title") as string);
|
||||
}
|
||||
|
||||
public MainWindowVm(MainWindow view)
|
||||
{
|
||||
Task.Run(async () => IsUpdateAvailable = await _updater.CheckForUpdates());
|
||||
_view = view;
|
||||
SetFolderPathCommand = new RelayCommand(OnFolderPathSelection);
|
||||
ApplyPatchCommand = new RelayCommand(OnPatching);
|
||||
RestoreBackupCommand = new RelayCommand(OnBackupRestoring);
|
||||
UpdateCommand = new RelayCommand(OnUpdate);
|
||||
OpenSettingsCommand = new RelayCommand(OnOpenSettings);
|
||||
|
||||
WeModInfo = Extensions.FindWeMod();
|
||||
if (WeModInfo == null)
|
||||
{
|
||||
Log("WeMod directory not found.", ELogType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user