mirror of
https://github.com/gwdevhub/Daybreak.git
synced 2026-09-17 22:05:08 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6c2d4a1e70 | ||
|
|
be03f1a32d | ||
|
|
3ed1cc453a | ||
|
|
16030063ed | ||
|
|
458696ad8f | ||
|
|
6201702563 | ||
|
|
c5bea23a8f | ||
|
|
e5f38f77ef | ||
|
|
1d774ab8de | ||
|
|
bc66ca9948 | ||
|
|
524cd21fd4 | ||
|
|
132cb0e1f4 | ||
|
|
09c99e7731 |
@@ -8,5 +8,9 @@ namespace Daybreak.Configuration
|
||||
public bool MultiLaunchSupport { get; set; }
|
||||
[JsonProperty("ToolboxAutoLaunchDelay")]
|
||||
public int ToolboxAutoLaunchDelay { get; set; } = 5000;
|
||||
[JsonProperty("DynamicBuildLoading")]
|
||||
public bool DynamicBuildLoading { get; set; } = true;
|
||||
[JsonProperty("LaunchGuildwarsAsCurrentUser")]
|
||||
public bool LaunchGuildwarsAsCurrentUser { get; set; } = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ using Daybreak.Services.Credentials;
|
||||
using Daybreak.Services.IconRetrieve;
|
||||
using Daybreak.Services.Logging;
|
||||
using Daybreak.Services.Mutex;
|
||||
using Daybreak.Services.Privilege;
|
||||
using Daybreak.Services.Runtime;
|
||||
using Daybreak.Services.Screenshots;
|
||||
using Daybreak.Services.Updater;
|
||||
@@ -37,6 +38,7 @@ namespace Daybreak.Configuration
|
||||
serviceProducer.RegisterSingleton<IRuntimeStore, RuntimeStore>();
|
||||
serviceProducer.RegisterSingleton<IBuildTemplateManager, BuildTemplateManager>();
|
||||
serviceProducer.RegisterSingleton<IIconRetriever, IconRetriever>();
|
||||
serviceProducer.RegisterSingleton<IPrivilegeManager, PrivilegeManager>();
|
||||
}
|
||||
public static void RegisterLifetimeServices(IApplicationLifetimeProducer applicationLifetimeProducer)
|
||||
{
|
||||
@@ -60,6 +62,7 @@ namespace Daybreak.Configuration
|
||||
viewProducer.RegisterView<ExecutablesView>();
|
||||
viewProducer.RegisterView<BuildTemplateView>();
|
||||
viewProducer.RegisterView<BuildsListView>();
|
||||
viewProducer.RegisterView<RequestElevationView>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<UserControl x:Class="Daybreak.Controls.HelpButton"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Daybreak.Controls"
|
||||
mc:Ignorable="d"
|
||||
x:Name="_this"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Viewbox>
|
||||
<Grid>
|
||||
<Ellipse x:Name="BackgroundEllipse" Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" Visibility="Visible" Opacity="0.1" Width="30" Height="30" />
|
||||
<Ellipse Width="30" Height="30" StrokeThickness="2" Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"></Ellipse>
|
||||
<Path Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" VerticalAlignment="Center" HorizontalAlignment="Center"
|
||||
Data="m4.99353,17.899l0,-1.47c0,-1.436 0.322,-2.188 1.075,-3.229l2.404,-3.3c1.254,-1.721 1.684,-2.546 1.684,-3.766c0,-2.044 -1.434,-3.335 -3.479,-3.335c-2.008,0 -3.299,1.219 -3.729,3.407c-0.036,0.215 -0.179,0.323 -0.395,0.287l-2.259,-0.395c-0.216,-0.036 -0.323,-0.179 -0.288,-0.395c0.539,-3.443 3.014,-5.703 6.744,-5.703c3.872,0 6.49,2.546 6.49,6.097c0,1.722 -0.608,2.977 -1.828,4.663l-2.403,3.3c-0.717,0.968 -0.933,1.47 -0.933,2.689l0,1.147c0,0.215 -0.143,0.358 -0.358,0.358l-2.367,0c-0.215,0.004 -0.358,-0.14 -0.358,-0.355zm-0.179,3.444c0,-0.215 0.143,-0.358 0.359,-0.358l2.726,0c0.215,0 0.358,0.144 0.358,0.358l0,3.084c0,0.216 -0.144,0.358 -0.358,0.358l-2.726,0c-0.217,0 -0.359,-0.143 -0.359,-0.358l0,-3.084z"></Path>
|
||||
<Ellipse Fill="Transparent" MouseEnter="Ellipse_MouseEnter" MouseLeave="Ellipse_MouseLeave" MouseLeftButtonDown="Ellipse_MouseLeftButtonDown"></Ellipse>
|
||||
</Grid>
|
||||
</Viewbox>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for AddButton.xaml
|
||||
/// </summary>
|
||||
public partial class HelpButton : UserControl
|
||||
{
|
||||
public event EventHandler Clicked;
|
||||
|
||||
public HelpButton()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0.6;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
this.Clicked?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,6 +138,7 @@ namespace Daybreak.Controls
|
||||
{
|
||||
await this.WebBrowser.EnsureCoreWebView2Async(this.coreWebView2Environment);
|
||||
this.AddressBarReadonly = this.configurationManager.GetConfiguration().AddressBarReadonly;
|
||||
this.CanDownloadBuild = this.configurationManager.GetConfiguration().ExperimentalFeatures.DynamicBuildLoading;
|
||||
this.WebBrowser.CoreWebView2.NewWindowRequested += (browser, args) => args.Handled = true;
|
||||
this.WebBrowser.NavigationStarting += (browser, args) =>
|
||||
{
|
||||
@@ -154,7 +155,10 @@ namespace Daybreak.Controls
|
||||
this.WebBrowser.WebMessageReceived += this.CoreWebView2_WebMessageReceived;
|
||||
this.WebBrowser.CoreWebView2.Settings.AreDevToolsEnabled = false;
|
||||
this.WebBrowser.CoreWebView2.Settings.AreDefaultContextMenusEnabled = false;
|
||||
await this.WebBrowser.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(Scripts.AlterContextMenu);
|
||||
if (this.CanDownloadBuild)
|
||||
{
|
||||
await this.WebBrowser.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(Scripts.SendSelectionOnContextMenu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,12 +214,17 @@ namespace Daybreak.Controls
|
||||
if (payload?.Key == BrowserPayload.PayloadKeys.ContextMenu)
|
||||
{
|
||||
var contextMenuPayload = args.WebMessageAsJson.Deserialize<BrowserPayload<OnContextMenuPayload>>();
|
||||
if (this.CanDownloadBuild is false)
|
||||
var maybeTemplate = contextMenuPayload.Value.Selection;
|
||||
if (string.IsNullOrWhiteSpace(maybeTemplate))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.buildTemplateManager.IsTemplate(maybeTemplate) is false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var maybeTemplate = contextMenuPayload.Value.Selection;
|
||||
Task.Run(() =>
|
||||
{
|
||||
try
|
||||
|
||||
@@ -4,17 +4,22 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Daybreak.Controls"
|
||||
mc:Ignorable="d"
|
||||
mc:Ignorable="d"
|
||||
x:Name="_this"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid>
|
||||
<WrapPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="10, 0, 10, 0">
|
||||
<local:HelpButton Width="20" Height="20" Margin="3, 0, 3, 0" Foreground="White"
|
||||
Clicked="HelpButton_Clicked" Cursor="Hand"></local:HelpButton>
|
||||
<TextBlock Text="{Binding Attribute.Name}" FontSize="16" Foreground="White"></TextBlock>
|
||||
</WrapPanel>
|
||||
<WrapPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="10, 0, 10, 0">
|
||||
<local:MinusButton Foreground="White" Height="20" Clicked="MinusButton_Clicked"></local:MinusButton>
|
||||
<local:MinusButton Foreground="White" Height="20" Clicked="MinusButton_Clicked" Cursor="Hand"
|
||||
IsEnabled="{Binding ElementName=_this, Path=CanSubtract, Mode=OneWay}"></local:MinusButton>
|
||||
<TextBox Background="Transparent" Foreground="White" FontSize="16" IsReadOnly="True" Width="30"
|
||||
Text="{Binding Points}"></TextBox>
|
||||
<local:AddButton Foreground="White" Height="20" Clicked="AddButton_Clicked"></local:AddButton>
|
||||
<local:AddButton Foreground="White" Height="20" Clicked="AddButton_Clicked" Cursor="Hand"
|
||||
IsEnabled="{Binding ElementName=_this, Path=CanAdd, Mode=OneWay}"></local:AddButton>
|
||||
</WrapPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
using Daybreak.Models.Builds;
|
||||
using System;
|
||||
using System.Extensions;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Extensions;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
{
|
||||
@@ -9,9 +12,45 @@ namespace Daybreak.Controls
|
||||
/// </summary>
|
||||
public partial class AttributeTemplate : UserControl
|
||||
{
|
||||
public readonly static DependencyProperty CanAddProperty =
|
||||
DependencyPropertyExtensions.Register<AttributeTemplate, bool>(nameof(CanAdd), new PropertyMetadata(false));
|
||||
public readonly static DependencyProperty CanSubtractProperty =
|
||||
DependencyPropertyExtensions.Register<AttributeTemplate, bool>(nameof(CanSubtract), new PropertyMetadata(false));
|
||||
|
||||
public event EventHandler<AttributeEntry> HelpClicked;
|
||||
|
||||
public bool CanAdd
|
||||
{
|
||||
get => this.GetTypedValue<bool>(CanAddProperty);
|
||||
private set => this.SetValue(CanAddProperty, value);
|
||||
}
|
||||
|
||||
public bool CanSubtract
|
||||
{
|
||||
get => this.GetTypedValue<bool>(CanSubtractProperty);
|
||||
private set => this.SetValue(CanSubtractProperty, value);
|
||||
}
|
||||
|
||||
public AttributeTemplate()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.InitializeComponent();
|
||||
this.DataContextChanged += AttributeTemplate_DataContextChanged;
|
||||
}
|
||||
|
||||
private void AttributeTemplate_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.NewValue is AttributeEntry attributeEntry)
|
||||
{
|
||||
if (attributeEntry.Points > 0)
|
||||
{
|
||||
this.CanSubtract = true;
|
||||
}
|
||||
|
||||
if (attributeEntry.Points < 12)
|
||||
{
|
||||
this.CanAdd = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void MinusButton_Clicked(object sender, System.EventArgs e)
|
||||
@@ -19,6 +58,8 @@ namespace Daybreak.Controls
|
||||
if (this.DataContext.As<AttributeEntry>().Points > 0)
|
||||
{
|
||||
this.DataContext.As<AttributeEntry>().Points--;
|
||||
this.CanSubtract = this.DataContext.As<AttributeEntry>().Points > 0;
|
||||
this.CanAdd = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +68,16 @@ namespace Daybreak.Controls
|
||||
if (this.DataContext.As<AttributeEntry>().Points < 12)
|
||||
{
|
||||
this.DataContext.As<AttributeEntry>().Points++;
|
||||
this.CanAdd = this.DataContext.As<AttributeEntry>().Points < 12;
|
||||
this.CanSubtract = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void HelpButton_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
if (this.DataContext is AttributeEntry attributeEntry)
|
||||
{
|
||||
this.HelpClicked?.Invoke(this, attributeEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,15 +24,16 @@
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"></ColumnDefinition>
|
||||
<ColumnDefinition Width="auto"></ColumnDefinition>
|
||||
<ColumnDefinition Width="*"></ColumnDefinition>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="Primary Profession: " FontSize="16" Foreground="White"></TextBlock>
|
||||
<ListView FontSize="16" Foreground="White" Grid.Column="1"
|
||||
<TextBlock Text="Primary Profession: " FontSize="16" Foreground="White" Grid.Column="1"></TextBlock>
|
||||
<ListView FontSize="16" Foreground="White" Grid.Column="2" BorderThickness="0"
|
||||
Background="Transparent" ItemsSource="{Binding ElementName=_this, Path=Professions, Mode=OneWay}"
|
||||
SelectedItem="{Binding ElementName=_this, Path=PrimaryProfession, Mode=TwoWay}" Height="25"
|
||||
SelectedItem="{Binding ElementName=_this, Path=PrimaryProfession, Mode=TwoWay}" Height="30"
|
||||
SelectionMode="Single" ScrollViewer.VerticalScrollBarVisibility="Disabled"
|
||||
PreviewMouseWheel="ListView_DisableMouseWheel">
|
||||
PreviewMouseWheel="ListView_NavigateWithMouseWheel">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Name, Mode=OneWay}"></TextBlock>
|
||||
@@ -42,18 +43,21 @@
|
||||
<behaviors:ScrollIntoView></behaviors:ScrollIntoView>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
</ListView>
|
||||
<local:HelpButton Grid.Column="0" Foreground="White" Width="20" Height="20" Margin="3"
|
||||
Clicked="HelpButtonPrimary_Clicked" Cursor="Hand"></local:HelpButton>
|
||||
</Grid>
|
||||
<Grid Grid.Row="2">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"></ColumnDefinition>
|
||||
<ColumnDefinition Width="auto"></ColumnDefinition>
|
||||
<ColumnDefinition Width="*"></ColumnDefinition>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="Secondary Profession: " FontSize="16" Foreground="White"></TextBlock>
|
||||
<ListView FontSize="16" Foreground="White" Grid.Column="1"
|
||||
<TextBlock Text="Secondary Profession: " FontSize="16" Foreground="White" Grid.Column="1"></TextBlock>
|
||||
<ListView FontSize="16" Foreground="White" Grid.Column="2" BorderThickness="0"
|
||||
Background="Transparent" ItemsSource="{Binding ElementName=_this, Path=Professions, Mode=OneWay}"
|
||||
SelectedItem="{Binding ElementName=_this, Path=SecondaryProfession, Mode=TwoWay}" Height="25"
|
||||
SelectedItem="{Binding ElementName=_this, Path=SecondaryProfession, Mode=TwoWay}" Height="30"
|
||||
SelectionMode="Single" ScrollViewer.VerticalScrollBarVisibility="Disabled"
|
||||
PreviewMouseWheel="ListView_DisableMouseWheel">
|
||||
PreviewMouseWheel="ListView_NavigateWithMouseWheel">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Name, Mode=OneWay}"></TextBlock>
|
||||
@@ -63,13 +67,15 @@
|
||||
<behaviors:ScrollIntoView></behaviors:ScrollIntoView>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
</ListView>
|
||||
<local:HelpButton Grid.Column="0" Foreground="White" Width="20" Height="20" Margin="3"
|
||||
Clicked="HelpButtonSecondary_Clicked" Cursor="Hand"></local:HelpButton>
|
||||
</Grid>
|
||||
<Grid Grid.Row="3">
|
||||
<ListBox Background="Transparent" ItemsSource="{Binding ElementName=_this, Path=Attributes, Mode=OneWay}"
|
||||
HorizontalContentAlignment="Stretch">
|
||||
HorizontalContentAlignment="Stretch" BorderThickness="0">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<local:AttributeTemplate></local:AttributeTemplate>
|
||||
<local:AttributeTemplate HelpClicked="AttributeTemplate_HelpClicked"></local:AttributeTemplate>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
@@ -90,42 +96,42 @@
|
||||
<RowDefinition Height="auto"></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<local:SkillTemplate Grid.Column="0"
|
||||
Foreground="White"
|
||||
Foreground="White" Cursor="Hand"
|
||||
FontSize="22" DataContext="{Binding ElementName=_this, Path=Skill0, Mode=TwoWay}"
|
||||
VerticalAlignment="Stretch" Clicked="SkillTemplate_Clicked"
|
||||
RemoveClicked="SkillTemplate_RemoveClicked"></local:SkillTemplate>
|
||||
<local:SkillTemplate Grid.Column="1"
|
||||
Foreground="White"
|
||||
Foreground="White" Cursor="Hand"
|
||||
FontSize="22" DataContext="{Binding ElementName=_this, Path=Skill1, Mode=TwoWay}"
|
||||
VerticalAlignment="Stretch" Clicked="SkillTemplate_Clicked"
|
||||
RemoveClicked="SkillTemplate_RemoveClicked"></local:SkillTemplate>
|
||||
<local:SkillTemplate Grid.Column="2"
|
||||
Foreground="White"
|
||||
Foreground="White" Cursor="Hand"
|
||||
FontSize="22" DataContext="{Binding ElementName=_this, Path=Skill2, Mode=TwoWay}"
|
||||
VerticalAlignment="Stretch" Clicked="SkillTemplate_Clicked"
|
||||
RemoveClicked="SkillTemplate_RemoveClicked"></local:SkillTemplate>
|
||||
<local:SkillTemplate Grid.Column="3"
|
||||
Foreground="White"
|
||||
Foreground="White" Cursor="Hand"
|
||||
FontSize="22" DataContext="{Binding ElementName=_this, Path=Skill3, Mode=TwoWay}"
|
||||
VerticalAlignment="Stretch" Clicked="SkillTemplate_Clicked"
|
||||
RemoveClicked="SkillTemplate_RemoveClicked"></local:SkillTemplate>
|
||||
<local:SkillTemplate Grid.Column="4"
|
||||
Foreground="White"
|
||||
Foreground="White" Cursor="Hand"
|
||||
FontSize="22" DataContext="{Binding ElementName=_this, Path=Skill4, Mode=TwoWay}"
|
||||
VerticalAlignment="Stretch" Clicked="SkillTemplate_Clicked"
|
||||
RemoveClicked="SkillTemplate_RemoveClicked"></local:SkillTemplate>
|
||||
<local:SkillTemplate Grid.Column="5"
|
||||
Foreground="White"
|
||||
Foreground="White" Cursor="Hand"
|
||||
FontSize="22" DataContext="{Binding ElementName=_this, Path=Skill5, Mode=TwoWay}"
|
||||
VerticalAlignment="Stretch" Clicked="SkillTemplate_Clicked"
|
||||
RemoveClicked="SkillTemplate_RemoveClicked"></local:SkillTemplate>
|
||||
<local:SkillTemplate Grid.Column="6"
|
||||
Foreground="White"
|
||||
Foreground="White" Cursor="Hand"
|
||||
FontSize="22" DataContext="{Binding ElementName=_this, Path=Skill6, Mode=TwoWay}"
|
||||
VerticalAlignment="Stretch" Clicked="SkillTemplate_Clicked"
|
||||
RemoveClicked="SkillTemplate_RemoveClicked"></local:SkillTemplate>
|
||||
<local:SkillTemplate Grid.Column="7"
|
||||
Foreground="White"
|
||||
Foreground="White" Cursor="Hand"
|
||||
FontSize="22" DataContext="{Binding ElementName=_this, Path=Skill7, Mode=TwoWay}"
|
||||
VerticalAlignment="Stretch" Clicked="SkillTemplate_Clicked"
|
||||
RemoveClicked="SkillTemplate_RemoveClicked"></local:SkillTemplate>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Daybreak.Launch;
|
||||
using Daybreak.Models.Builds;
|
||||
using Daybreak.Services.IconRetrieve;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Extensions;
|
||||
@@ -20,8 +21,8 @@ namespace Daybreak.Controls
|
||||
/// </summary>
|
||||
public partial class BuildTemplate : UserControl
|
||||
{
|
||||
private const string SkillNamePlaceholder = "[NAME]";
|
||||
private const string BaseAddress = $"https://wiki.guildwars.com/wiki/{SkillNamePlaceholder}";
|
||||
private const string InfoNamePlaceholder = "[NAME]";
|
||||
private const string BaseAddress = $"https://wiki.guildwars.com/wiki/{InfoNamePlaceholder}";
|
||||
|
||||
public readonly static DependencyProperty PrimaryProfessionProperty =
|
||||
DependencyPropertyExtensions.Register<BuildTemplate, Profession>(nameof(PrimaryProfession), new PropertyMetadata(Profession.None));
|
||||
@@ -137,8 +138,8 @@ namespace Daybreak.Controls
|
||||
|
||||
private void Grid_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||
{
|
||||
this.SkillBrowser.Width = 0;
|
||||
this.SkillsListView.Width = 0;
|
||||
this.HideSkillListView();
|
||||
this.HideInfoBrowser();
|
||||
}
|
||||
|
||||
private void LoadAttributes()
|
||||
@@ -244,21 +245,79 @@ namespace Daybreak.Controls
|
||||
this.Skill7 = build.Build.Skills[7];
|
||||
}
|
||||
|
||||
private void BrowseToInfo(string infoName)
|
||||
{
|
||||
var address = BaseAddress.Replace(InfoNamePlaceholder, infoName.Replace(" ", "_"));
|
||||
this.SkillBrowser.Address = address;
|
||||
this.ShowInfoBrowser();
|
||||
}
|
||||
|
||||
private void ShowInfoBrowser()
|
||||
{
|
||||
this.SkillBrowser.Width = 400;
|
||||
this.SkillsListView.Width = 0;
|
||||
}
|
||||
|
||||
private void HideInfoBrowser()
|
||||
{
|
||||
this.SkillBrowser.Width = 0;
|
||||
}
|
||||
|
||||
private void ShowSkillListView()
|
||||
{
|
||||
this.SkillBrowser.Width = 0;
|
||||
this.SkillsListView.Width = 400;
|
||||
}
|
||||
|
||||
private void HideSkillListView()
|
||||
{
|
||||
this.SkillsListView.Width = 0;
|
||||
}
|
||||
|
||||
private void HelpButtonPrimary_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
if (this.PrimaryProfession == Profession.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.BrowseToInfo(PrimaryProfession.Name);
|
||||
if (e is RoutedEventArgs routedEventArgs)
|
||||
{
|
||||
routedEventArgs.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void HelpButtonSecondary_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
if (this.SecondaryProfession == Profession.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.BrowseToInfo(this.SecondaryProfession.Name);
|
||||
if (e is RoutedEventArgs routedEventArgs)
|
||||
{
|
||||
routedEventArgs.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void AttributeTemplate_HelpClicked(object sender, AttributeEntry e)
|
||||
{
|
||||
this.BrowseToInfo(e.Attribute.Name);
|
||||
}
|
||||
|
||||
private void SkillTemplate_Clicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var skill = sender.As<SkillTemplate>().DataContext.As<Skill>();
|
||||
if (skill == Skill.NoSkill)
|
||||
{
|
||||
this.SkillsListView.Width = 400;
|
||||
this.SkillBrowser.Width = 0;
|
||||
this.ShowSkillListView();
|
||||
this.selectingSkillTemplate = sender.As<SkillTemplate>();
|
||||
}
|
||||
else
|
||||
{
|
||||
var address = BaseAddress.Replace(SkillNamePlaceholder, skill.Name.Replace(" ", "_"));
|
||||
this.SkillBrowser.Address = address;
|
||||
this.SkillBrowser.Width = 400;
|
||||
this.SkillsListView.Width = 0;
|
||||
this.BrowseToInfo(skill.Name);
|
||||
}
|
||||
e.Handled = true;
|
||||
}
|
||||
@@ -272,12 +331,12 @@ namespace Daybreak.Controls
|
||||
{
|
||||
if (this.selectingSkillTemplate is null)
|
||||
{
|
||||
this.SkillsListView.Width = 0;
|
||||
this.HideSkillListView();
|
||||
return;
|
||||
}
|
||||
|
||||
this.selectingSkillTemplate.DataContext = sender.As<ListView>().SelectedItem;
|
||||
this.SkillsListView.Width = 0;
|
||||
this.HideSkillListView();
|
||||
this.loadedBuild.Build.Skills[0] = Skill0;
|
||||
this.loadedBuild.Build.Skills[1] = Skill1;
|
||||
this.loadedBuild.Build.Skills[2] = Skill2;
|
||||
@@ -288,9 +347,21 @@ namespace Daybreak.Controls
|
||||
this.loadedBuild.Build.Skills[7] = Skill7;
|
||||
}
|
||||
|
||||
private void ListView_DisableMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
|
||||
private void ListView_NavigateWithMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
|
||||
{
|
||||
e.Handled = true;
|
||||
if (e.Delta > 0)
|
||||
{
|
||||
sender.As<ListView>().SelectedIndex = sender.As<ListView>().SelectedIndex > 0 ?
|
||||
sender.As<ListView>().SelectedIndex - 1 :
|
||||
0;
|
||||
}
|
||||
else
|
||||
{
|
||||
sender.As<ListView>().SelectedIndex = sender.As<ListView>().SelectedIndex < sender.As<ListView>().Items.Count - 1 ?
|
||||
sender.As<ListView>().SelectedIndex + 1 :
|
||||
sender.As<ListView>().Items.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,11 @@
|
||||
<RowDefinition Height="*"></RowDefinition>
|
||||
<RowDefinition Height="auto"></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<Image VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
|
||||
Source="{Binding ElementName=_this, Path=ImageSource, Mode=OneWay}"></Image>
|
||||
<Image VerticalAlignment="Top" HorizontalAlignment="Left"
|
||||
Width="{Binding ElementName=_this, Path=ActualWidth, Mode=OneWay}"
|
||||
Height="{Binding ElementName=_this, Path=ActualWidth, Mode=OneWay}"
|
||||
Source="{Binding ElementName=_this, Path=ImageSource, Mode=OneWay}"
|
||||
Stretch="UniformToFill"></Image>
|
||||
<Border BorderThickness="5" BorderBrush="Black"></Border>
|
||||
<Border BorderThickness="5" BorderBrush="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
Opacity="{Binding ElementName=_this, Path=BorderOpacity, Mode=OneWay}"></Border>
|
||||
|
||||
@@ -48,15 +48,22 @@ namespace Daybreak.Controls
|
||||
|
||||
private void SkillTemplate_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.NewValue is Skill)
|
||||
if (e.NewValue is Skill skill)
|
||||
{
|
||||
Task.Run(() => GetImageStream(e.NewValue.As<Skill>())).ContinueWith((previousTask) =>
|
||||
if (skill != Skill.NoSkill)
|
||||
{
|
||||
this.Dispatcher.Invoke(() =>
|
||||
Task.Run(() => GetImageStream(skill)).ContinueWith((previousTask) =>
|
||||
{
|
||||
this.ImageSource = GetImageSource(previousTask.Result);
|
||||
this.Dispatcher.Invoke(() =>
|
||||
{
|
||||
this.ImageSource = GetImageSource(previousTask.Result);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
else if (this.ImageSource is not null)
|
||||
{
|
||||
this.ImageSource = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,22 +9,25 @@
|
||||
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
|
||||
<LangVersion>preview</LangVersion>
|
||||
<ApplicationIcon>Daybreak.ico</ApplicationIcon>
|
||||
<Version>0.7.0</Version>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
<Version>0.8.0</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="HtmlAgilityPack" Version="1.11.32" />
|
||||
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.774.44" />
|
||||
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.818.41" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="Slim" Version="1.2.1" />
|
||||
<PackageReference Include="System.Windows.Interactivity.WPF" Version="2.0.20525" />
|
||||
<PackageReference Include="SystemExtensions.NetStandard" Version="1.1.3" />
|
||||
<PackageReference Include="SystemExtensions.NetStandard" Version="1.1.4" />
|
||||
<PackageReference Include="WCL" Version="1.0.2" />
|
||||
<PackageReference Include="WpfExtended" Version="0.2.0" />
|
||||
<PackageReference Include="WpfScreenHelper" Version="1.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Controls\Buttons\HelpButton.xaml.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Controls\Buttons\MinusButton.xaml.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
@@ -37,6 +40,10 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\Buttons\HelpButton.xaml">
|
||||
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Update="Controls\Buttons\MinusButton.xaml">
|
||||
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
|
||||
<SubType>Designer</SubType>
|
||||
|
||||
@@ -9,6 +9,8 @@ using Microsoft.Web.WebView2.Wpf;
|
||||
using Slim;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Extensions;
|
||||
@@ -45,6 +47,18 @@ namespace Daybreak.Launch
|
||||
MessageBox.Show(fatalException.ToString());
|
||||
return false;
|
||||
}
|
||||
else if (e is AggregateException aggregateException)
|
||||
{
|
||||
if (aggregateException.InnerExceptions.FirstOrDefault() is COMException comException &&
|
||||
comException.Message.Contains("Invalid window handle"))
|
||||
{
|
||||
/*
|
||||
* Ignore exception caused by browser failing to initialize due to missing window.
|
||||
* Likely caused by switching windows before browser was initialized.
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
MessageBox.Show(e.ToString());
|
||||
return true;
|
||||
|
||||
@@ -89,6 +89,7 @@ namespace Daybreak.Models.Builds
|
||||
Motivation,
|
||||
Leadership,
|
||||
ScytheMastery,
|
||||
EarthPrayers,
|
||||
WindPrayers,
|
||||
EarthMagic,
|
||||
Mysticism
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
|
||||
namespace Daybreak.Models
|
||||
{
|
||||
public sealed class ElevationRequest
|
||||
{
|
||||
public object DataContext { get; set; }
|
||||
public Type View { get; set; }
|
||||
public string MessageToUser { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,9 @@ using Daybreak.Services.Configuration;
|
||||
using Daybreak.Services.Credentials;
|
||||
using Daybreak.Services.Logging;
|
||||
using Daybreak.Services.Mutex;
|
||||
using Daybreak.Services.Privilege;
|
||||
using Daybreak.Utils;
|
||||
using Daybreak.Views;
|
||||
using Microsoft.Win32;
|
||||
using Pepa.Wpf.Utilities;
|
||||
using System;
|
||||
@@ -15,6 +17,7 @@ using System.Linq;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace Daybreak.Services.ApplicationLauncher
|
||||
{
|
||||
@@ -30,6 +33,7 @@ namespace Daybreak.Services.ApplicationLauncher
|
||||
private readonly ICredentialManager credentialManager;
|
||||
private readonly IMutexHandler mutexHandler;
|
||||
private readonly ILogger logger;
|
||||
private readonly IPrivilegeManager privilegeManager;
|
||||
|
||||
public bool IsTexmodRunning => TexModProcessDetected();
|
||||
public bool IsGuildwarsRunning => this.GuildwarsProcessDetected();
|
||||
@@ -39,12 +43,14 @@ namespace Daybreak.Services.ApplicationLauncher
|
||||
IConfigurationManager configurationManager,
|
||||
ICredentialManager credentialManager,
|
||||
IMutexHandler mutexHandler,
|
||||
ILogger logger)
|
||||
ILogger logger,
|
||||
IPrivilegeManager privilegeManager)
|
||||
{
|
||||
this.logger = logger.ThrowIfNull(nameof(logger));
|
||||
this.mutexHandler = mutexHandler.ThrowIfNull(nameof(mutexHandler));
|
||||
this.credentialManager = credentialManager.ThrowIfNull(nameof(credentialManager));
|
||||
this.configurationManager = configurationManager.ThrowIfNull(nameof(configurationManager));
|
||||
this.privilegeManager = privilegeManager.ThrowIfNull(nameof(privilegeManager));
|
||||
}
|
||||
|
||||
public async Task LaunchGuildwars()
|
||||
@@ -56,6 +62,12 @@ namespace Daybreak.Services.ApplicationLauncher
|
||||
{
|
||||
if (configuration.ExperimentalFeatures.MultiLaunchSupport is true)
|
||||
{
|
||||
if (this.privilegeManager.AdminPrivileges is false)
|
||||
{
|
||||
this.privilegeManager.RequestAdminPrivileges<MainView>("You need administrator rights in order to start using multi-launch");
|
||||
return;
|
||||
}
|
||||
|
||||
ClearGwLocks();
|
||||
}
|
||||
|
||||
@@ -103,6 +115,33 @@ namespace Daybreak.Services.ApplicationLauncher
|
||||
});
|
||||
}
|
||||
|
||||
public void RestartDaybreakAsAdmin()
|
||||
{
|
||||
this.logger.LogInformation("Restarting daybreak with admin rights");
|
||||
var processName = Process.GetCurrentProcess()?.MainModule?.FileName;
|
||||
if (processName.IsNullOrWhiteSpace() || File.Exists(processName) is false)
|
||||
{
|
||||
throw new InvalidOperationException("Unable to find executable. Aborting restart");
|
||||
}
|
||||
|
||||
var process = new Process()
|
||||
{
|
||||
StartInfo = new()
|
||||
{
|
||||
Verb = "runas",
|
||||
WorkingDirectory = Environment.CurrentDirectory,
|
||||
UseShellExecute = true,
|
||||
FileName = processName
|
||||
}
|
||||
};
|
||||
if (process.Start() is false)
|
||||
{
|
||||
throw new InvalidOperationException($"Unable to start {processName} as admin");
|
||||
}
|
||||
|
||||
Application.Current.Shutdown();
|
||||
}
|
||||
|
||||
private void LaunchGuildwarsProcess(string email, Models.SecureString password, string character)
|
||||
{
|
||||
var executable = this.configurationManager.GetConfiguration().GuildwarsPaths.Where(path => path.Default).FirstOrDefault();
|
||||
@@ -129,6 +168,18 @@ namespace Daybreak.Services.ApplicationLauncher
|
||||
args.Add(character);
|
||||
}
|
||||
|
||||
var identity = this.configurationManager.GetConfiguration().ExperimentalFeatures.LaunchGuildwarsAsCurrentUser ?
|
||||
System.Security.Principal.WindowsIdentity.GetCurrent().Name :
|
||||
System.Security.Principal.WindowsIdentity.GetAnonymous().Name;
|
||||
this.logger.LogInformation($"Launching guildwars as [{identity}] identity");
|
||||
var process = new Process()
|
||||
{
|
||||
StartInfo = new ProcessStartInfo
|
||||
{
|
||||
Arguments = string.Join(" ", args),
|
||||
UserName = identity
|
||||
}
|
||||
};
|
||||
if (Process.Start(executable.Path, args) is null)
|
||||
{
|
||||
throw new InvalidOperationException($"Unable to launch {executable}");
|
||||
|
||||
@@ -10,5 +10,6 @@ namespace Daybreak.Services.ApplicationLauncher
|
||||
Task LaunchGuildwars();
|
||||
Task LaunchGuildwarsToolbox();
|
||||
Task LaunchTexmod();
|
||||
void RestartDaybreakAsAdmin();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,21 @@ namespace Daybreak.Services.BuildTemplates
|
||||
this.logger = logger.ThrowIfNull(nameof(logger));
|
||||
}
|
||||
|
||||
public bool IsTemplate(string template)
|
||||
{
|
||||
if (template.IsNullOrWhiteSpace())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (template.Where(c => DecodingLookupTable.Contains(c) is false).Any())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public BuildEntry CreateBuild()
|
||||
{
|
||||
var emptyBuild = new Build();
|
||||
@@ -53,13 +68,12 @@ namespace Daybreak.Services.BuildTemplates
|
||||
public void SaveBuild(BuildEntry buildEntry)
|
||||
{
|
||||
var encodedBuild = this.EncodeTemplate(buildEntry.Build);
|
||||
File.WriteAllText($"{BuildsPath}\\{buildEntry.Name}.txt", encodedBuild);
|
||||
if (string.IsNullOrWhiteSpace(buildEntry.PreviousName))
|
||||
{
|
||||
return;
|
||||
File.Delete($"{BuildsPath}\\{buildEntry.PreviousName}.txt");
|
||||
}
|
||||
|
||||
File.Delete($"{BuildsPath}\\{buildEntry.PreviousName}.txt");
|
||||
File.WriteAllText($"{BuildsPath}\\{buildEntry.Name}.txt", encodedBuild);
|
||||
}
|
||||
|
||||
public void RemoveBuild(BuildEntry buildEntry)
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace Daybreak.Services.BuildTemplates
|
||||
{
|
||||
public interface IBuildTemplateManager
|
||||
{
|
||||
bool IsTemplate(string template);
|
||||
BuildEntry CreateBuild();
|
||||
BuildEntry CreateBuild(string name);
|
||||
void SaveBuild(BuildEntry buildEntry);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Windows.Controls;
|
||||
using System;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Services.ViewManagement
|
||||
{
|
||||
@@ -11,5 +12,9 @@ namespace Daybreak.Services.ViewManagement
|
||||
|
||||
void ShowView<T>(object dataContext)
|
||||
where T : UserControl;
|
||||
|
||||
void ShowView(Type type);
|
||||
|
||||
void ShowView(Type type, object dataContext);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Slim;
|
||||
using System;
|
||||
using System.Extensions;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Services.ViewManagement
|
||||
@@ -32,17 +33,33 @@ namespace Daybreak.Services.ViewManagement
|
||||
|
||||
public void ShowView<T>() where T : UserControl
|
||||
{
|
||||
var view = this.serviceManager.GetService<T>();
|
||||
this.container.Children.Clear();
|
||||
this.container.Children.Add(view);
|
||||
this.ShowViewInner(typeof(T), null);
|
||||
}
|
||||
|
||||
public void ShowView<T>(object dataContext) where T : UserControl
|
||||
{
|
||||
var view = this.serviceManager.GetService<T>();
|
||||
this.container.Children.Clear();
|
||||
this.container.Children.Add(view);
|
||||
view.DataContext = dataContext;
|
||||
this.ShowViewInner(typeof(T), dataContext);
|
||||
}
|
||||
|
||||
public void ShowView(Type type)
|
||||
{
|
||||
this.ShowViewInner(type, null);
|
||||
}
|
||||
|
||||
public void ShowView(Type type, object dataContext)
|
||||
{
|
||||
this.ShowViewInner(type, dataContext);
|
||||
}
|
||||
|
||||
private void ShowViewInner(Type viewType, object dataContext)
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
var view = this.serviceManager.GetService(viewType).As<UserControl>();
|
||||
this.container.Children.Clear();
|
||||
this.container.Children.Add(view);
|
||||
view.DataContext = dataContext;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Services.Privilege
|
||||
{
|
||||
public interface IPrivilegeManager
|
||||
{
|
||||
bool AdminPrivileges { get; }
|
||||
|
||||
void RequestAdminPrivileges<TCancelView>(string messageToUser, object dataContextOfCancelView = null)
|
||||
where TCancelView : UserControl;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using Daybreak.Models;
|
||||
using Daybreak.Services.Logging;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using Daybreak.Utils;
|
||||
using Daybreak.Views;
|
||||
using System.Extensions;
|
||||
using System.Security.Principal;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Services.Privilege
|
||||
{
|
||||
public sealed class PrivilegeManager : IPrivilegeManager
|
||||
{
|
||||
public bool AdminPrivileges => new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);
|
||||
|
||||
private readonly IViewManager viewManager;
|
||||
private readonly ILogger logger;
|
||||
|
||||
public PrivilegeManager(
|
||||
IViewManager viewManager,
|
||||
ILogger logger)
|
||||
{
|
||||
this.logger = logger.ThrowIfNull(nameof(logger));
|
||||
this.viewManager = viewManager.ThrowIfNull(nameof(viewManager));
|
||||
}
|
||||
|
||||
public void RequestAdminPrivileges<TCancelView>(string messageToUser, object dataContextOfCancelView = null)
|
||||
where TCancelView : UserControl
|
||||
{
|
||||
this.logger.LogInformation("Requesting admin privileges");
|
||||
this.viewManager.ShowView<RequestElevationView>(new ElevationRequest { View = typeof(TCancelView), DataContext = dataContextOfCancelView, MessageToUser = messageToUser });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ namespace Daybreak.Services.Updater
|
||||
{
|
||||
public sealed class ApplicationUpdater : IApplicationUpdater
|
||||
{
|
||||
private const string LaunchActionName = "Launch_Daybreak";
|
||||
private const string UpdateDesiredKey = "UpdateDesired";
|
||||
private const string ExecutionPolicyKey = "ExecutionPolicy";
|
||||
private const string UpdatedKey = "Updating";
|
||||
@@ -32,13 +33,20 @@ namespace Daybreak.Services.Updater
|
||||
private const string OutputPathTag = "{OUTPUTPATH}";
|
||||
private const string ExecutionPolicyTag = "{EXECUTIONPOLICY}";
|
||||
private const string ProcessIdTag = "{PROCESSID}";
|
||||
private const string ExecutableNameTag = "{EXECUTABLE}";
|
||||
private const string WorkingDirectoryTag = "{WORKINGDIRECTORY}";
|
||||
private const string Url = "https://github.com/AlexMacocian/Daybreak/releases/latest";
|
||||
private const string DownloadUrl = $"https://github.com/AlexMacocian/Daybreak/releases/download/v{VersionTag}/Daybreakv{VersionTag}.zip";
|
||||
private const string GetExecutionPolicyCommand = "Get-ExecutionPolicy -Scope CurrentUser";
|
||||
private const string SetExecutionPolicyCommand = $"Set-ExecutionPolicy {ExecutionPolicyTag} -Scope CurrentUser";
|
||||
private const string WaitCommand = $"Wait-Process -Id {ProcessIdTag}";
|
||||
private const string ExtractCommandTemplate = $"Expand-Archive -Path '{InputFileTag}' -DestinationPath '{OutputPathTag}' -Force";
|
||||
private const string RunClientCommand = @".\Daybreak.exe";
|
||||
private const string PrepareScheduledAction = $"$action = New-ScheduledTaskAction -Execute {ExecutableNameTag} -WorkingDirectory {WorkingDirectoryTag}";
|
||||
private const string PrepareTriggerForAction = $"$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date)";
|
||||
private const string RegisterScheduledAction = $"Register-ScheduledTask -Action $action -Trigger $trigger -TaskName {LaunchActionName} | Out-Null";
|
||||
private const string LaunchScheduledAction = $"Start-ScheduledTask -TaskName {LaunchActionName}";
|
||||
private const string SleepOneSecond = $"Start-Sleep -s 1";
|
||||
private const string UnregisterScheduledAction = $"Unregister-ScheduledTask -TaskName {LaunchActionName} -Confirm:$false";
|
||||
private const string RemoveTempFile = $"Remove-item {TempFile}";
|
||||
private const string RemovePs1 = $"Remove-item {ExtractAndRunPs1}";
|
||||
|
||||
@@ -251,8 +259,15 @@ namespace Daybreak.Services.Updater
|
||||
.Replace(InputFileTag, Path.GetFullPath(TempFile))
|
||||
.Replace(OutputPathTag, Directory.GetCurrentDirectory()),
|
||||
RemoveTempFile,
|
||||
PrepareScheduledAction
|
||||
.Replace(ExecutableNameTag, Process.GetCurrentProcess()?.MainModule?.FileName)
|
||||
.Replace(WorkingDirectoryTag, Directory.GetCurrentDirectory()),
|
||||
PrepareTriggerForAction,
|
||||
RegisterScheduledAction,
|
||||
LaunchScheduledAction,
|
||||
SleepOneSecond,
|
||||
UnregisterScheduledAction,
|
||||
RemovePs1,
|
||||
RunClientCommand
|
||||
});
|
||||
var process = new Process()
|
||||
{
|
||||
@@ -260,12 +275,10 @@ namespace Daybreak.Services.Updater
|
||||
{
|
||||
FileName = "powershell.exe",
|
||||
Arguments = $@"{Directory.GetCurrentDirectory()}\{ExtractAndRunPs1}",
|
||||
UseShellExecute = false,
|
||||
RedirectStandardError = true,
|
||||
RedirectStandardInput = true,
|
||||
RedirectStandardOutput = true,
|
||||
UseShellExecute = true,
|
||||
WindowStyle = ProcessWindowStyle.Maximized,
|
||||
WorkingDirectory = Directory.GetCurrentDirectory()
|
||||
WorkingDirectory = Directory.GetCurrentDirectory(),
|
||||
Verb = "runas"
|
||||
},
|
||||
};
|
||||
this.logger.LogInformation("Created extractor script. Attempting to launch powershell");
|
||||
|
||||
@@ -2,17 +2,21 @@
|
||||
{
|
||||
public static class Scripts
|
||||
{
|
||||
public const string AlterContextMenu = @"
|
||||
public const string SendSelectionOnContextMenu = @"
|
||||
document.addEventListener('contextmenu', function (event)
|
||||
{
|
||||
var text = '';
|
||||
if (window.getSelection)
|
||||
var activeEl = document.activeElement;
|
||||
var activeElTagName = activeEl ? activeEl.tagName.toLowerCase() : null;
|
||||
if ((activeElTagName == 'textarea') || (activeElTagName == 'input' &&
|
||||
/^(?:text|search|password|tel|url)$/i.test(activeEl.type)) &&
|
||||
(typeof activeEl.selectionStart == 'number'))
|
||||
{
|
||||
text = activeEl.value.slice(activeEl.selectionStart, activeEl.selectionEnd);
|
||||
}
|
||||
else if (window.getSelection)
|
||||
{
|
||||
text = window.getSelection().toString();
|
||||
}
|
||||
else if (document.selection && document.selection.type != 'Control')
|
||||
{
|
||||
text = document.selection.createRange().text;
|
||||
}
|
||||
|
||||
let jsonObject =
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Daybreak.Services.Logging;
|
||||
using Daybreak.Services.Privilege;
|
||||
using Daybreak.Services.Runtime;
|
||||
using Daybreak.Services.Updater;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
@@ -18,18 +19,32 @@ namespace Daybreak.Views
|
||||
private readonly ILogger logger;
|
||||
private readonly IViewManager viewManager;
|
||||
private readonly IRuntimeStore runtimeStore;
|
||||
private readonly IPrivilegeManager privilegeManager;
|
||||
|
||||
public AskUpdateView(
|
||||
ILogger logger,
|
||||
IViewManager viewManager,
|
||||
IRuntimeStore runtimeStore)
|
||||
IRuntimeStore runtimeStore,
|
||||
IPrivilegeManager privilegeManager)
|
||||
{
|
||||
this.logger = logger.ThrowIfNull(nameof(logger));
|
||||
this.viewManager = viewManager.ThrowIfNull(nameof(viewManager));
|
||||
this.runtimeStore = runtimeStore.ThrowIfNull(nameof(runtimeStore));
|
||||
this.privilegeManager = privilegeManager.ThrowIfNull(nameof(privilegeManager));
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private bool CheckIfAdmin()
|
||||
{
|
||||
if (this.privilegeManager.AdminPrivileges is false)
|
||||
{
|
||||
this.privilegeManager.RequestAdminPrivileges<MainView>("Application needs to be in administrator mode in order to update.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void NoButton_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
this.logger.LogInformation("User declined update");
|
||||
@@ -41,6 +56,11 @@ namespace Daybreak.Views
|
||||
{
|
||||
this.logger.LogInformation("User accepted update");
|
||||
this.runtimeStore.StoreValue(UpdateDesiredKey, true);
|
||||
if (this.CheckIfAdmin() is false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.viewManager.ShowView<UpdateView>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,6 +90,8 @@
|
||||
<StackPanel>
|
||||
<TextBlock Text="Multi-launch support" Foreground="White" FontSize="22" VerticalAlignment="Center" Margin="0, 0, 15, 0" Height="30"></TextBlock>
|
||||
<TextBlock Text="GWToolbox startup delay (in ms)" Foreground="White" FontSize="22" VerticalAlignment="Center" Margin="0, 0, 15, 0" Height="30"></TextBlock>
|
||||
<TextBlock Text="Detect build templates (in browser)" Foreground="White" FontSize="22" VerticalAlignment="Center" Margin="0, 0, 15, 0" Height="30"></TextBlock>
|
||||
<TextBlock Text="Launch gw as current user" Foreground="White" FontSize="22" VerticalAlignment="Center" Margin="0, 0, 15, 0" Height="30"></TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Column="1">
|
||||
<ToggleButton IsChecked="{Binding ElementName=_this, Path=MultiLaunch, Mode=TwoWay}" Style="{StaticResource AnimatedSwitch}"
|
||||
@@ -97,6 +99,10 @@
|
||||
<TextBox Background="Transparent" Foreground="White" FontSize="16" Height="30"
|
||||
PreviewTextInput="TextBox_AllowNumbersOnly" Text="{Binding ElementName=_this, Path=GWToolboxLaunchDelay, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
CommandManager.PreviewCanExecute="TextBox_DisallowPaste"></TextBox>
|
||||
<ToggleButton IsChecked="{Binding ElementName=_this, Path=DynamicBuildLoading, Mode=TwoWay}" Style="{StaticResource AnimatedSwitch}"
|
||||
Height="30" Width="60"></ToggleButton>
|
||||
<ToggleButton IsChecked="{Binding ElementName=_this, Path=LaunchAsCurrentUser, Mode=TwoWay}" Style="{StaticResource AnimatedSwitch}"
|
||||
Height="30" Width="60"></ToggleButton>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
@@ -19,10 +19,19 @@ namespace Daybreak.Views
|
||||
DependencyPropertyExtensions.Register<ExperimentalSettingsView, bool>(nameof(MultiLaunch));
|
||||
public static readonly DependencyProperty GWToolboxLaunchDelayProperty =
|
||||
DependencyPropertyExtensions.Register<ExperimentalSettingsView, string>(nameof(GWToolboxLaunchDelay));
|
||||
public static readonly DependencyProperty DynamicBuildLoadingProperty =
|
||||
DependencyPropertyExtensions.Register<ExperimentalSettingsView, bool>(nameof(DynamicBuildLoading));
|
||||
public static readonly DependencyProperty LaunchAsCurrentUserProperty =
|
||||
DependencyPropertyExtensions.Register<ExperimentalSettingsView, bool>(nameof(LaunchAsCurrentUser));
|
||||
|
||||
private readonly IViewManager viewManager;
|
||||
private readonly IConfigurationManager configurationManager;
|
||||
|
||||
public bool LaunchAsCurrentUser
|
||||
{
|
||||
get => this.GetTypedValue<bool>(LaunchAsCurrentUserProperty);
|
||||
set => this.SetValue(LaunchAsCurrentUserProperty, value);
|
||||
}
|
||||
public bool MultiLaunch
|
||||
{
|
||||
get => this.GetTypedValue<bool>(MultiLaunchProperty);
|
||||
@@ -33,6 +42,11 @@ namespace Daybreak.Views
|
||||
get => this.GetTypedValue<string>(GWToolboxLaunchDelayProperty);
|
||||
set => this.SetValue(GWToolboxLaunchDelayProperty, value);
|
||||
}
|
||||
public bool DynamicBuildLoading
|
||||
{
|
||||
get => this.GetTypedValue<bool>(DynamicBuildLoadingProperty);
|
||||
set => this.SetValue(DynamicBuildLoadingProperty, value);
|
||||
}
|
||||
|
||||
public ExperimentalSettingsView(
|
||||
IViewManager viewManager,
|
||||
@@ -49,12 +63,16 @@ namespace Daybreak.Views
|
||||
var config = this.configurationManager.GetConfiguration();
|
||||
this.MultiLaunch = config.ExperimentalFeatures.MultiLaunchSupport;
|
||||
this.GWToolboxLaunchDelay = config.ExperimentalFeatures.ToolboxAutoLaunchDelay.ToString();
|
||||
this.DynamicBuildLoading = config.ExperimentalFeatures.DynamicBuildLoading;
|
||||
this.LaunchAsCurrentUser = config.ExperimentalFeatures.LaunchGuildwarsAsCurrentUser;
|
||||
}
|
||||
|
||||
private void SaveExperimentalSettings()
|
||||
{
|
||||
var config = this.configurationManager.GetConfiguration();
|
||||
config.ExperimentalFeatures.MultiLaunchSupport = this.MultiLaunch;
|
||||
config.ExperimentalFeatures.DynamicBuildLoading = this.DynamicBuildLoading;
|
||||
config.ExperimentalFeatures.LaunchGuildwarsAsCurrentUser = this.LaunchAsCurrentUser;
|
||||
if (int.TryParse(this.GWToolboxLaunchDelay, out var gwToolboxLaunchDelay))
|
||||
{
|
||||
config.ExperimentalFeatures.ToolboxAutoLaunchDelay = gwToolboxLaunchDelay;
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<UserControl x:Class="Daybreak.Views.RequestElevationView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Daybreak.Views"
|
||||
mc:Ignorable="d"
|
||||
xmlns:controls="clr-namespace:Daybreak.Controls"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid VerticalAlignment="Center" HorizontalAlignment="Center" Background="White" MinHeight="200" MinWidth="400">
|
||||
<StackPanel VerticalAlignment="Center" Orientation="Vertical">
|
||||
<TextBlock Text="{Binding MessageToUser}" Margin="10, 0, 10, 0" Foreground="Black"
|
||||
TextWrapping="Wrap" HorizontalAlignment="Center" FontSize="16"></TextBlock>
|
||||
<TextBlock Text="Do you want to restart the application with administrator rights?" HorizontalAlignment="Center"
|
||||
FontSize="16" Foreground="Black" Margin="10, 0, 10, 10"></TextBlock>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"></ColumnDefinition>
|
||||
<ColumnDefinition Width="*"></ColumnDefinition>
|
||||
</Grid.ColumnDefinitions>
|
||||
<controls:OpaqueButton Text="Yes" BackgroundOpacity="0.2" TransparentBackground="Gray" HorizontalAlignment="Center" Margin="10" Width="50" Height="25"
|
||||
Clicked="YesButton_Clicked" Foreground="Black" FontSize="16"></controls:OpaqueButton>
|
||||
<controls:OpaqueButton Text="No" BackgroundOpacity="0.2" TransparentBackground="Gray" HorizontalAlignment="Center" Margin="10" Width="50" Height="25"
|
||||
Clicked="NoButton_Clicked" Foreground="Black" Grid.Column="1" FontSize="16"></controls:OpaqueButton>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,51 @@
|
||||
using Daybreak.Models;
|
||||
using Daybreak.Services.ApplicationLauncher;
|
||||
using Daybreak.Services.Logging;
|
||||
using Daybreak.Services.Privilege;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using Daybreak.Utils;
|
||||
using System.Extensions;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for RequestElevationView.xaml
|
||||
/// </summary>
|
||||
public partial class RequestElevationView : UserControl
|
||||
{
|
||||
private readonly IApplicationLauncher applicationLauncher;
|
||||
private readonly IViewManager viewManager;
|
||||
private readonly ILogger logger;
|
||||
|
||||
public RequestElevationView(
|
||||
IApplicationLauncher applicationLauncher,
|
||||
IViewManager viewManager,
|
||||
ILogger logger)
|
||||
{
|
||||
this.applicationLauncher = applicationLauncher.ThrowIfNull(nameof(applicationLauncher));
|
||||
this.viewManager = viewManager.ThrowIfNull(nameof(viewManager));
|
||||
this.logger = logger.ThrowIfNull(nameof(logger));
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void YesButton_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
this.applicationLauncher.RestartDaybreakAsAdmin();
|
||||
}
|
||||
|
||||
private void NoButton_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
if (this.DataContext is ElevationRequest elevationRequest)
|
||||
{
|
||||
this.logger.LogWarning($"Elevation request denied. Showing {elevationRequest.View} with {elevationRequest.DataContext}");
|
||||
this.viewManager.ShowView(elevationRequest.View, elevationRequest.DataContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.logger.LogWarning("Elevation request context is not set. Returning to home page");
|
||||
this.viewManager.ShowView<MainView>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
||||
<security>
|
||||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
||||
</application>
|
||||
</compatibility>
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
</assembly>
|
||||
@@ -5,6 +5,8 @@ Requires webview2 runtime https://go.microsoft.com/fwlink/p/?LinkId=2124703.
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
# Features
|
||||
Automatically detect if guildwars is running or not. Includes the ability to launch guildwars from the client.
|
||||
@@ -43,3 +45,13 @@ To adjust executables, go into Guildwars settings. Clicking on the star next to
|
||||
|
||||
To enable multiboxing (multi-launch), go into Experimental settings. Then, switch between executables/accounts and launch them.
|
||||

|
||||
|
||||
To manage builds, go into Settings, Builds. Here you can select/remove builds.
|
||||

|
||||
|
||||
Doubleclick on one of the builds to enter the template management view. Here you can click on skills to open the wiki page of the skill. You can adjust professions, attributes and add/remove skills.
|
||||

|
||||
|
||||
To dynamically load a build, while browsing in the browsers from the main page, select and rightclick any text on the page that might be a template. If it is a template, the client will open a context menu with a button called "Load build template". Click on that button to load the build and switch to build template view.
|
||||
|
||||

|
||||
|
||||
Reference in New Issue
Block a user