0
0
mirror of https://github.com/sp-tarkov/patcher.git synced 2025-02-12 20:50:46 -05:00

added projects, added original patcher utils files, patcher client port WIP

This commit is contained in:
IsWaffle 2021-12-11 21:47:59 -05:00
parent 277a59cc7f
commit 1ee9044544
55 changed files with 2784 additions and 0 deletions

View File

@ -0,0 +1,454 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# Tye
.tye/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
##
## Visual studio for Mac
##
# globs
Makefile.in
*.userprefs
*.usertasks
config.make
config.status
aclocal.m4
install-sh
autom4te.cache/
*.tar.gz
tarballs/
test-results/
# Mac bundle stuff
*.dmg
*.app
# content below from: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# content below from: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore
# Windows thumbnail cache files
Thumbs.db
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# JetBrains Rider
.idea/
*.sln.iml
##
## Visual Studio Code
##
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json

View File

@ -0,0 +1,12 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:PatchClient"
x:Class="PatchClient.App">
<Application.DataTemplates>
<local:ViewLocator/>
</Application.DataTemplates>
<Application.Styles>
<FluentTheme Mode="Light"/>
</Application.Styles>
</Application>

View File

@ -0,0 +1,29 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using PatchClient.ViewModels;
using PatchClient.Views;
namespace PatchClient
{
public class App : Application
{
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
}
public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.MainWindow = new MainWindow
{
DataContext = new MainWindowViewModel(),
};
}
base.OnFrameworkInitializationCompleted();
}
}
}

View File

@ -0,0 +1,13 @@
<Styles xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Design.PreviewWith>
<Border Padding="20">
<!-- Add Controls for Previewer Here -->
</Border>
</Design.PreviewWith>
<!-- Add Styles Here -->
<Style Selector="Label.blue">
<Setter Property="Foreground" Value="DodgerBlue"/>
</Style>
</Styles>

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

View File

@ -0,0 +1,39 @@
using PatcherUtils;
using ReactiveUI;
using System;
namespace PatchClient.Models
{
public class LineItemProgress : ReactiveObject
{
private int total = 0;
private string _Info = "";
public string Info
{
get => _Info;
set => this.RaiseAndSetIfChanged(ref _Info, value);
}
private int _Progress;
public int Progress
{
get => _Progress;
set => this.RaiseAndSetIfChanged(ref _Progress, value);
}
public void UpdateProgress(int Count)
{
Progress = (int)Math.Floor((double)Count / total * 100);
}
public LineItemProgress(LineItem Item)
{
Info = Item.ItemText;
total = Item.ItemValue;
Progress = (int)Math.Floor((double)Item.ItemValue / total * 100);
}
}
}

View File

@ -0,0 +1,14 @@
using ReactiveUI;
namespace PatchClient.Models
{
public class ViewNavigator : ReactiveObject
{
private object _SelectedViewModel;
public object SelectedViewModel
{
get => _SelectedViewModel;
set => this.RaiseAndSetIfChanged(ref _SelectedViewModel, value);
}
}
}

View File

@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<AvaloniaResource Include="Assets\**" />
<AvaloniaResource Remove="Assets\Styles.axaml" />
<None Remove=".gitignore" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PatcherUtils\PatcherUtils.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="0.10.10" />
<PackageReference Include="Avalonia.Desktop" Version="0.10.10" />
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="0.10.10" />
<PackageReference Include="Avalonia.ReactiveUI" Version="0.10.10" />
</ItemGroup>
<ItemGroup>
<AvaloniaXaml Update="Assets\Styles.axaml">
<SubType>Designer</SubType>
</AvaloniaXaml>
</ItemGroup>
</Project>

View File

@ -0,0 +1,24 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.ReactiveUI;
using System;
namespace PatchClient
{
class Program
{
// Initialization code. Don't use any Avalonia, third-party APIs or any
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
// yet and stuff might break.
[STAThread]
public static void Main(string[] args) => BuildAvaloniaApp()
.StartWithClassicDesktopLifetime(args);
// Avalonia configuration, don't remove; also used by visual designer.
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UsePlatformDetect()
.LogToTrace()
.UseReactiveUI();
}
}

View File

@ -0,0 +1,30 @@
using Avalonia.Controls;
using Avalonia.Controls.Templates;
using PatchClient.ViewModels;
using System;
namespace PatchClient
{
public class ViewLocator : IDataTemplate
{
public IControl Build(object data)
{
var name = data.GetType().FullName!.Replace("ViewModel", "View");
var type = Type.GetType(name);
if (type != null)
{
return (Control)Activator.CreateInstance(type)!;
}
else
{
return new TextBlock { Text = "Not Found: " + name };
}
}
public bool Match(object data)
{
return data is ViewModelBase;
}
}
}

View File

@ -0,0 +1,16 @@
using PatchClient.Models;
using Splat;
namespace PatchClient.ViewModels
{
public class MainWindowViewModel : ViewModelBase
{
public ViewNavigator navigator { get; set; } = new ViewNavigator();
public MainWindowViewModel()
{
navigator.SelectedViewModel = new PatcherViewModel();
Locator.CurrentMutable.RegisterConstant(navigator, typeof(ViewNavigator));
}
}
}

View File

@ -0,0 +1,20 @@
using Avalonia;
using ReactiveUI;
namespace PatchClient.ViewModels
{
public class MessageViewModel : ViewModelBase
{
private string _InfoText;
public string InfoText
{
get => _InfoText;
set => this.RaiseAndSetIfChanged(ref _InfoText, value);
}
public MessageViewModel(string Message)
{
InfoText = Message;
}
}
}

View File

@ -0,0 +1,133 @@
using Avalonia;
using PatchClient.Models;
using PatcherUtils;
using Splat;
using System;
using ReactiveUI;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Avalonia.Controls.ApplicationLifetimes;
using System.Collections.ObjectModel;
namespace PatchClient.ViewModels
{
public class PatcherViewModel : ViewModelBase
{
private bool initLineItemProgress = true;
public ObservableCollection<LineItemProgress> LineItems { get; set; } = new ObservableCollection<LineItemProgress>();
private string _ProgressMessage;
public string ProgressMessage
{
get => _ProgressMessage;
set => this.RaiseAndSetIfChanged(ref _ProgressMessage, value);
}
private int _PatchProgress;
public int PatchProgress
{
get => _PatchProgress;
set => this.RaiseAndSetIfChanged(ref _PatchProgress, value);
}
private string _PatchMessage;
public string PatchMessage
{
get => _PatchMessage;
set => this.RaiseAndSetIfChanged(ref _PatchMessage, value);
}
private ViewNavigator navigator => Locator.Current.GetService<ViewNavigator>();
public PatcherViewModel()
{
Test();
}
[Obsolete]
private void Test()
{
Task.Run(() =>
{
LineItem x = new LineItem("test 1", 100);
LineItem xx = new LineItem("test 2", 100);
LineItem xxx = new LineItem("test 3", 100);
LineItems.Add(new LineItemProgress(x));
LineItems.Add(new LineItemProgress(xx));
LineItems.Add(new LineItemProgress(xxx));
for (int i = 0; i <= 100; i++)
{
System.Threading.Thread.Sleep(20);
PatchProgress = i;
ProgressMessage = $"Patching @ {i}%";
foreach(var item in LineItems)
{
item.UpdateProgress(i);
}
}
navigator.SelectedViewModel = new MessageViewModel("Patch completed without issues");
});
}
private void RunPatcher()
{
Task.Run(() =>
{
FilePatcher bp = new FilePatcher()
{
TargetBase = Environment.CurrentDirectory,
PatchBase = LazyOperations.PatchFolder.FromCwd()
};
bp.ProgressChanged += Bp_ProgressChanged;
try
{
if (bp.Run())
{
navigator.SelectedViewModel = new MessageViewModel("Patch completed without issues");
}
else
{
navigator.SelectedViewModel = new MessageViewModel("Failed to patch client");
}
}
catch (Exception ex)
{
navigator.SelectedViewModel = new MessageViewModel(ex.Message);
}
});
}
private void Bp_ProgressChanged(object Sender, int Progress, int Total, int Percent, string Message = "", params LineItem[] AdditionalLineItems)
{
foreach (LineItem item in AdditionalLineItems)
{
if(initLineItemProgress)
{
LineItems.Add(new LineItemProgress(item));
}
LineItems.FirstOrDefault(x => x.Info == item.ItemText).UpdateProgress(item.ItemValue);
}
initLineItemProgress = false;
PatchProgress = Progress;
if (!string.IsNullOrWhiteSpace(Message))
{
PatchMessage = Message;
}
ProgressMessage = $"Patching @ {Percent}%";
}
}
}

View File

@ -0,0 +1,11 @@
using ReactiveUI;
using System;
using System.Collections.Generic;
using System.Text;
namespace PatchClient.ViewModels
{
public class ViewModelBase : ReactiveObject
{
}
}

View File

@ -0,0 +1,21 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:PatchClient.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="PatchClient.Views.MainWindow"
Icon="/Assets/avalonia-logo.ico"
Title="Patch Client"
Height="300" Width="600"
WindowStartupLocation="CenterScreen"
>
<Design.DataContext>
<vm:MainWindowViewModel/>
</Design.DataContext>
<DockPanel LastChildFill="True">
<ContentControl Content="{Binding navigator.SelectedViewModel}"/>
</DockPanel>
</Window>

View File

@ -0,0 +1,22 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace PatchClient.Views
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
#if DEBUG
this.AttachDevTools();
#endif
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
}

View File

@ -0,0 +1,20 @@
<UserControl xmlns="https://github.com/avaloniaui"
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"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="PatchClient.Views.MessageView">
<UserControl.Styles>
<StyleInclude Source="/Assets/Styles.axaml"/>
</UserControl.Styles>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<Label Content="You can close this window"
FontSize="12" FontWeight="SemiBold"/>
<Label Content="{Binding InfoText}"
Classes="blue"
/>
</StackPanel>
</UserControl>

View File

@ -0,0 +1,19 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace PatchClient.Views
{
public partial class MessageView : UserControl
{
public MessageView()
{
InitializeComponent();
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
}

View File

@ -0,0 +1,41 @@
<UserControl xmlns="https://github.com/avaloniaui"
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:model="using:PatchClient.Models"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="PatchClient.Views.PatcherView">
<UserControl.Styles>
<StyleInclude Source="/Assets/Styles.axaml"/>
<Style Selector="Label">
<Setter Property="Margin" Value="0 0 0 5"/>
</Style>
</UserControl.Styles>
<Grid RowDefinitions="AUTO,AUTO,AUTO,AUTO,AUTO" Margin="10">
<!-- Current Patch Text -->
<Label Content="{Binding ProgressMessage}"/>
<Label Content="{Binding PatchMessage}" Grid.Row="1"
Classes="blue"/>
<ProgressBar Grid.Row="2" Value="{Binding PatchProgress}"/>
<Separator Grid.Row="3"
VerticalAlignment="Bottom"
Background="Gainsboro"
Height="1"
Margin="0 20"/>
<ItemsControl Items="{Binding LineItems}" Grid.Row="4" HorizontalAlignment="Stretch">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type model:LineItemProgress}">
<StackPanel Orientation="Horizontal">
<Label Content="{Binding Info}"/>
<ProgressBar Value="{Binding Progress}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</UserControl>

View File

@ -0,0 +1,19 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace PatchClient.Views
{
public partial class PatcherView : UserControl
{
public PatcherView()
{
InitializeComponent();
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
}

View File

@ -0,0 +1,454 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# Tye
.tye/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
##
## Visual studio for Mac
##
# globs
Makefile.in
*.userprefs
*.usertasks
config.make
config.status
aclocal.m4
install-sh
autom4te.cache/
*.tar.gz
tarballs/
test-results/
# Mac bundle stuff
*.dmg
*.app
# content below from: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# content below from: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore
# Windows thumbnail cache files
Thumbs.db
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# JetBrains Rider
.idea/
*.sln.iml
##
## Visual Studio Code
##
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json

View File

@ -0,0 +1,12 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:PatchGenerator"
x:Class="PatchGenerator.App">
<Application.DataTemplates>
<local:ViewLocator/>
</Application.DataTemplates>
<Application.Styles>
<FluentTheme Mode="Light"/>
</Application.Styles>
</Application>

View File

@ -0,0 +1,29 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using PatchGenerator.ViewModels;
using PatchGenerator.Views;
namespace PatchGenerator
{
public class App : Application
{
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
}
public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.MainWindow = new MainWindow
{
DataContext = new MainWindowViewModel(),
};
}
base.OnFrameworkInitializationCompleted();
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

View File

@ -0,0 +1,36 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\PatcherUtils\PatcherUtils.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="Aki.ByteBanger">
<HintPath>References\Aki.ByteBanger.dll</HintPath>
</Reference>
<Reference Include="Aki.Common">
<HintPath>References\Aki.Common.dll</HintPath>
</Reference>
<Reference Include="ComponentAce.Compression.Libs.zlib">
<HintPath>References\ComponentAce.Compression.Libs.zlib.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Folder Include="Models\" />
<AvaloniaResource Include="Assets\**" />
<None Remove=".gitignore" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="0.10.10" />
<PackageReference Include="Avalonia.Desktop" Version="0.10.10" />
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="0.10.10" />
<PackageReference Include="Avalonia.ReactiveUI" Version="0.10.10" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,24 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.ReactiveUI;
using System;
namespace PatchGenerator
{
class Program
{
// Initialization code. Don't use any Avalonia, third-party APIs or any
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
// yet and stuff might break.
[STAThread]
public static void Main(string[] args) => BuildAvaloniaApp()
.StartWithClassicDesktopLifetime(args);
// Avalonia configuration, don't remove; also used by visual designer.
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UsePlatformDetect()
.LogToTrace()
.UseReactiveUI();
}
}

View File

@ -0,0 +1,30 @@
using Avalonia.Controls;
using Avalonia.Controls.Templates;
using PatchGenerator.ViewModels;
using System;
namespace PatchGenerator
{
public class ViewLocator : IDataTemplate
{
public IControl Build(object data)
{
var name = data.GetType().FullName!.Replace("ViewModel", "View");
var type = Type.GetType(name);
if (type != null)
{
return (Control)Activator.CreateInstance(type)!;
}
else
{
return new TextBlock { Text = "Not Found: " + name };
}
}
public bool Match(object data)
{
return data is ViewModelBase;
}
}
}

View File

@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace PatchGenerator.ViewModels
{
public class MainWindowViewModel : ViewModelBase
{
public string Greeting => "Welcome to Avalonia!";
}
}

View File

@ -0,0 +1,11 @@
using ReactiveUI;
using System;
using System.Collections.Generic;
using System.Text;
namespace PatchGenerator.ViewModels
{
public class ViewModelBase : ReactiveObject
{
}
}

View File

@ -0,0 +1,17 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:PatchGenerator.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="PatchGenerator.Views.MainWindow"
Icon="/Assets/avalonia-logo.ico"
Title="PatchGenerator">
<Design.DataContext>
<vm:MainWindowViewModel/>
</Design.DataContext>
<TextBlock Text="{Binding Greeting}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Window>

View File

@ -0,0 +1,22 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace PatchGenerator.Views
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
#if DEBUG
this.AttachDevTools();
#endif
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
}

View File

@ -0,0 +1,37 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31727.386
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PatchClient", "PatchClient\PatchClient.csproj", "{1C297369-03CA-4CA8-A651-22568A1CA310}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PatchGenerator", "PatchGenerator\PatchGenerator.csproj", "{0E0664C4-E698-41E4-919F-892D627739EA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PatcherUtils", "PatcherUtils\PatcherUtils.csproj", "{C84233F8-6630-4322-9FB6-0A957F39CDA7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1C297369-03CA-4CA8-A651-22568A1CA310}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1C297369-03CA-4CA8-A651-22568A1CA310}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1C297369-03CA-4CA8-A651-22568A1CA310}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1C297369-03CA-4CA8-A651-22568A1CA310}.Release|Any CPU.Build.0 = Release|Any CPU
{0E0664C4-E698-41E4-919F-892D627739EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0E0664C4-E698-41E4-919F-892D627739EA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0E0664C4-E698-41E4-919F-892D627739EA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0E0664C4-E698-41E4-919F-892D627739EA}.Release|Any CPU.Build.0 = Release|Any CPU
{C84233F8-6630-4322-9FB6-0A957F39CDA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C84233F8-6630-4322-9FB6-0A957F39CDA7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C84233F8-6630-4322-9FB6-0A957F39CDA7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C84233F8-6630-4322-9FB6-0A957F39CDA7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {07AD7FB8-3529-4A2A-BDD5-76F779273B9B}
EndGlobalSection
EndGlobal

454
Patcher/_port/Patcher/Patcher/.gitignore vendored Normal file
View File

@ -0,0 +1,454 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# Tye
.tye/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
##
## Visual studio for Mac
##
# globs
Makefile.in
*.userprefs
*.usertasks
config.make
config.status
aclocal.m4
install-sh
autom4te.cache/
*.tar.gz
tarballs/
test-results/
# Mac bundle stuff
*.dmg
*.app
# content below from: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# content below from: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore
# Windows thumbnail cache files
Thumbs.db
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# JetBrains Rider
.idea/
*.sln.iml
##
## Visual Studio Code
##
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json

View File

@ -0,0 +1,12 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Patcher"
x:Class="Patcher.App">
<Application.DataTemplates>
<local:ViewLocator/>
</Application.DataTemplates>
<Application.Styles>
<FluentTheme Mode="Light"/>
</Application.Styles>
</Application>

View File

@ -0,0 +1,29 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using Patcher.ViewModels;
using Patcher.Views;
namespace Patcher
{
public class App : Application
{
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
}
public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.MainWindow = new MainWindow
{
DataContext = new MainWindowViewModel(),
};
}
base.OnFrameworkInitializationCompleted();
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

View File

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Folder Include="Models\" />
<AvaloniaResource Include="Assets\**" />
<None Remove=".gitignore" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="0.10.10" />
<PackageReference Include="Avalonia.Desktop" Version="0.10.10" />
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="0.10.10" />
<PackageReference Include="Avalonia.ReactiveUI" Version="0.10.10" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,24 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.ReactiveUI;
using System;
namespace Patcher
{
class Program
{
// Initialization code. Don't use any Avalonia, third-party APIs or any
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
// yet and stuff might break.
[STAThread]
public static void Main(string[] args) => BuildAvaloniaApp()
.StartWithClassicDesktopLifetime(args);
// Avalonia configuration, don't remove; also used by visual designer.
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UsePlatformDetect()
.LogToTrace()
.UseReactiveUI();
}
}

View File

@ -0,0 +1,30 @@
using Avalonia.Controls;
using Avalonia.Controls.Templates;
using Patcher.ViewModels;
using System;
namespace Patcher
{
public class ViewLocator : IDataTemplate
{
public IControl Build(object data)
{
var name = data.GetType().FullName!.Replace("ViewModel", "View");
var type = Type.GetType(name);
if (type != null)
{
return (Control)Activator.CreateInstance(type)!;
}
else
{
return new TextBlock { Text = "Not Found: " + name };
}
}
public bool Match(object data)
{
return data is ViewModelBase;
}
}
}

View File

@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Patcher.ViewModels
{
public class MainWindowViewModel : ViewModelBase
{
public string Greeting => "Welcome to Avalonia!";
}
}

View File

@ -0,0 +1,11 @@
using ReactiveUI;
using System;
using System.Collections.Generic;
using System.Text;
namespace Patcher.ViewModels
{
public class ViewModelBase : ReactiveObject
{
}
}

View File

@ -0,0 +1,17 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:Patcher.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Patcher.Views.MainWindow"
Icon="/Assets/avalonia-logo.ico"
Title="Patcher">
<Design.DataContext>
<vm:MainWindowViewModel/>
</Design.DataContext>
<TextBlock Text="{Binding Greeting}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Window>

View File

@ -0,0 +1,22 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace Patcher.Views
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
#if DEBUG
this.AttachDevTools();
#endif
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
}

View File

@ -0,0 +1,185 @@
// NOTES:
// - redo search pattern;
// - compare both directories against eachother, not just one to the other
// - add ability to handle missing directories
using System.IO;
using Aki.Common.Utils;
using Aki.ByteBanger;
using System;
using System.Collections.Generic;
using System.Linq;
namespace PatcherUtils
{
public class FileCompare
{
public string PatchBase;
public string TargetBase;
public string CompareBase;
private int fileCount;
private int fileIt;
private int diffCount = 0;
private int newCount = 0;
private int delCount = 0;
private int matchCount = 0;
private List<FileInfo> TargetPaths;
private List<FileInfo> ComparePaths;
private List<LineItem> AdditionalInfo = new List<LineItem>();
/// <summary>
/// Provides patch generation progress changes
/// </summary>
public event ProgressChangedHandler ProgressChanged;
protected virtual void RaiseProgressChanged(int progress, int total, string Message = "", params LineItem[] AdditionalLineItems)
{
int percent = (int)Math.Floor((double)progress / total * 100);
ProgressChanged?.Invoke(this, progress, total, percent, Message, AdditionalLineItems);
}
/// <summary>
/// Compare a target file to an assumed compareable file.
/// </summary>
/// <param name="targetFile">The known target path</param>
/// <param name="assumedCompareFile">The assumed comparable file path</param>
/// <returns>True if a comparison was made | False if a comparison could not be made</returns>
private bool Compare(string targetFile, string assumedCompareFile)
{
string patchFilePath = targetFile.Replace(TargetBase, PatchBase);
//we know our target file exists
byte[] targetData = VFS.ReadFile(targetFile);
if(!File.Exists(assumedCompareFile))
{
//save the data we won't have in our target as new
VFS.WriteFile($"{patchFilePath}.new", Zlib.Compress(targetData, ZlibCompression.Maximum));
newCount++;
return true;
}
//now our compare file is known to exist
byte[] compareData = VFS.ReadFile(assumedCompareFile);
// get diffs
DiffResult result = PatchUtil.Diff(compareData, targetData);
switch (result.Result)
{
case DiffResultType.Success:
VFS.WriteFile($"{patchFilePath}.bpf", result.PatchInfo.ToBytes());
diffCount++;
return true;
case DiffResultType.FilesMatch:
matchCount++;
return true;
default:
return false;
}
}
/// <summary>
/// Compares the base folders and generates patch files.
/// </summary>
/// <returns>True if patches were generated successfully | False if patch generation failed</returns>
public bool CompareAll()
{
DirectoryInfo targetDirInfo = new DirectoryInfo(TargetBase);
DirectoryInfo compareDirInfo = new DirectoryInfo(CompareBase);
AdditionalInfo.Add(new LineItem("Diff Patch", 0));
AdditionalInfo.Add(new LineItem("New Patch", 0));
AdditionalInfo.Add(new LineItem("Del Patch", 0));
AdditionalInfo.Add(new LineItem("Files Match", 0));
if (!targetDirInfo.Exists || !compareDirInfo.Exists)
{
Console.WriteLine("Target or Compare folder does not exist");
return false;
}
//Get all the files recursively
TargetPaths = new List<FileInfo>(targetDirInfo.GetFiles("*.*", SearchOption.AllDirectories));
ComparePaths = new List<FileInfo>(compareDirInfo.GetFiles("*.*", SearchOption.AllDirectories));
RaiseProgressChanged(0, fileCount, "Generating diffs...");
/* Comparing Target files -> Compare files
* - Exists = Diff (.bfd file)
* - Doesn't Exist = New (.new file)
*
* Once everything has been compared from one side, any remaining paths in our ComparePaths
* are things that don't exist in our target and can be deleted (.del file)
*/
for (int x = 0; x < TargetPaths.Count; x++)
{
FileInfo file = TargetPaths[x];
string assumedComparePath = file.DirectoryName.Replace(TargetBase, CompareBase);
if (!Compare(file.FullName, VFS.Combine(assumedComparePath, file.Name)))
{
return false;
}
//remove any existing files from our ComparePaths
FileInfo assumedFile = new FileInfo(VFS.Combine(assumedComparePath, file.Name));
if (assumedFile.Exists && ComparePaths.Exists(x => x.FullName == assumedFile.FullName))
{
ComparePaths.Remove(ComparePaths.Where(x => x.FullName == assumedFile.FullName).FirstOrDefault());
}
AdditionalInfo[0].ItemValue = diffCount;
AdditionalInfo[1].ItemValue = newCount;
AdditionalInfo[3].ItemValue = matchCount;
fileIt++;
RaiseProgressChanged(fileIt, fileCount, file.Name, AdditionalInfo.ToArray());
}
if (ComparePaths.Count == 0)
{
//if there are no files to delete, just return true
return true;
}
//progress reset for files that need to be deleted
RaiseProgressChanged(0, ComparePaths.Count, "Processing .del files...");
fileIt = 0;
fileCount = ComparePaths.Count;
//the paths remaining in ComparePaths don't exist in our target and need to be removed during patching.
foreach (FileInfo file in ComparePaths)
{
//add del files replace root dir with patch base
string patchFilePath = file.FullName.Replace(CompareBase, PatchBase);
VFS.WriteFile($"{patchFilePath}.del", new byte[0]);
delCount++;
AdditionalInfo[2].ItemValue = delCount;
fileIt++;
RaiseProgressChanged(fileIt, fileCount, "", AdditionalInfo.ToArray());
}
return true;
}
public FileCompare(string TargetBase, string CompareBase, string PatchBase)
{
this.TargetBase = TargetBase;
this.CompareBase = CompareBase;
this.PatchBase = PatchBase;
fileCount = VFS.GetFilesCount(TargetBase);
fileIt = 0;
}
}
}

View File

@ -0,0 +1,147 @@
using System;
using System.IO;
using Aki.Common.Utils;
using Aki.ByteBanger;
using System.Collections.Generic;
using System.Linq;
namespace PatcherUtils
{
public class FilePatcher
{
public string TargetBase;
public string PatchBase;
private int fileCount;
private int fileIt;
private int diffCount;
private int newCount;
private int delCount;
private List<LineItem> AdditionalInfo;
public event ProgressChangedHandler ProgressChanged;
protected virtual void RaiseProgressChanged(int progress, int total, string Message = "", params LineItem[] AdditionalLineItems)
{
int percent = (int)Math.Floor((double)progress / total * 100);
ProgressChanged?.Invoke(this, progress, total, percent, Message, AdditionalLineItems);
}
public bool Patch(string targetfile, string patchfile)
{
byte[] target = VFS.ReadFile(targetfile);
byte[] patch = VFS.ReadFile(patchfile);
PatchResult result = PatchUtil.Patch(target, PatchInfo.FromBytes(patch));
switch (result.Result)
{
case PatchResultType.Success:
VFS.WriteFile(targetfile, result.PatchedData);
return true;
case PatchResultType.AlreadyPatched:
case PatchResultType.InputChecksumMismatch:
case PatchResultType.InputLengthMismatch:
return true;
case PatchResultType.OutputChecksumMismatch:
default:
return false;
}
}
private bool PatchAll(string targetpath, string patchpath)
{
DirectoryInfo di = new DirectoryInfo(patchpath);
foreach (FileInfo file in di.GetFiles())
{
FileInfo target = null;
switch (file.Extension)
{
// patch
case ".bpf":
{
target = new FileInfo(VFS.Combine(targetpath, file.Name.Replace(".bpf", "")));
if (!Patch(target.FullName, file.FullName))
{
// patch failed
return false;
}
diffCount--;
}
break;
// add new files
case ".new":
{
target = new FileInfo(VFS.Combine(targetpath, file.Name.Replace(".new", "")));
VFS.WriteFile(target.FullName, Zlib.Decompress(VFS.ReadFile(file.FullName)));
newCount--;
}
break;
// delete old files
case ".del":
{
target = new FileInfo(VFS.Combine(targetpath, file.Name.Replace(".del", "")));
target.IsReadOnly = false;
target.Delete();
delCount--;
}
break;
}
AdditionalInfo[0].ItemValue = diffCount;
AdditionalInfo[1].ItemValue = newCount;
AdditionalInfo[2].ItemValue = delCount;
++fileIt;
RaiseProgressChanged(fileIt, fileCount, target.Name, AdditionalInfo.ToArray());
}
foreach (DirectoryInfo directory in di.GetDirectories())
{
PatchAll(VFS.Combine(targetpath, directory.Name), directory.FullName);
}
di.Refresh();
if (di.GetFiles().Length == 0 && di.GetDirectories().Length == 0)
{
// remove empty folders
di.Delete();
}
return true;
}
public bool Run()
{
fileCount = VFS.GetFilesCount(PatchBase);
FileInfo[] files = new DirectoryInfo(PatchBase).GetFiles("*.*", SearchOption.AllDirectories);
diffCount = files.Where(x => x.Extension == ".bpf").Count();
newCount = files.Where(x => x.Extension == ".new").Count();
delCount = files.Where(x => x.Extension == ".del").Count();
AdditionalInfo = new List<LineItem>()
{
new LineItem("Patches Remaining", diffCount),
new LineItem("New Files to Inflate", newCount),
new LineItem("Files to Delete", delCount)
};
fileIt = 0;
return PatchAll(TargetBase, PatchBase);
}
}
}

View File

@ -0,0 +1,104 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
namespace PatcherUtils
{
public class LazyOperations
{
/// <summary>
/// A directory to store temporary data.
/// </summary>
public static string TempDir = "PATCHER_TEMP".FromCwd();
private static string SevenZExe = "7za.exe";
/// <summary>
/// The folder that the patches will be stored in
/// </summary>
public static string PatchFolder = "Aki_Data\\Patcher";
/// <summary>
/// The path to the 7za.exe file in the <see cref="TempDir"/>
/// </summary>
public static string SevenZExePath = $"{TempDir}\\{SevenZExe}";
private static string PatcherClient = "PatchClient.exe";
/// <summary>
/// The path to the patcher.exe file in the <see cref="TempDir"/>
/// </summary>
public static string PatcherClientPath = $"{TempDir}\\{PatcherClient}";
/// <summary>
/// Streams embedded resources out of the assembly
/// </summary>
/// <param name="ResourceName"></param>
/// <param name="OutputFilePath"></param>
/// <remarks>The resource will not be streamed out if the <paramref name="OutputFilePath"/> already exists</remarks>
private static void StreamResourceOut(string ResourceName, string OutputFilePath)
{
FileInfo outputFile = new FileInfo(OutputFilePath);
if (outputFile.Exists) return;
if (!outputFile.Directory.Exists)
{
Directory.CreateDirectory(outputFile.Directory.FullName);
}
using (FileStream fs = File.Create(OutputFilePath))
using (Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream(ResourceName))
{
s.CopyTo(fs);
}
}
/// <summary>
/// Checks the resources in the assembly and streams them to the temp directory for later use.
/// </summary>
public static void PrepTempDir()
{
foreach(string resource in Assembly.GetExecutingAssembly().GetManifestResourceNames())
{
switch(resource)
{
case string a when a.EndsWith(SevenZExe):
{
StreamResourceOut(resource, SevenZExePath);
break;
}
case string a when a.EndsWith(PatcherClient):
{
StreamResourceOut(resource, PatcherClientPath);
break;
}
}
}
}
public static void StartZipProcess(string SourcePath, string DestinationPath)
{
ProcessStartInfo procInfo = new ProcessStartInfo()
{
FileName = SevenZExePath,
Arguments = $"a {DestinationPath} {SourcePath}"
};
Process.Start(procInfo);
}
/// <summary>
/// Deletes the <see cref="TempDir"/> recursively
/// </summary>
public static void CleanupTempDir()
{
DirectoryInfo dir = new DirectoryInfo(TempDir);
if(dir.Exists)
{
dir.Delete(true);
}
}
}
}

View File

@ -0,0 +1,14 @@
namespace PatcherUtils
{
public class LineItem
{
public string ItemText;
public int ItemValue;
public LineItem(string ItemText, int ItemValue = 0)
{
this.ItemText = ItemText;
this.ItemValue = ItemValue;
}
}
}

View File

@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<None Remove="Resources\7za.exe" />
<None Remove="Resources\PatchClient.exe" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\7za.exe" />
<EmbeddedResource Include="Resources\PatchClient.exe" />
</ItemGroup>
<ItemGroup>
<Reference Include="Aki.ByteBanger">
<HintPath>..\PatchGenerator\References\Aki.ByteBanger.dll</HintPath>
</Reference>
<Reference Include="Aki.Common">
<HintPath>..\PatchGenerator\References\Aki.Common.dll</HintPath>
</Reference>
<Reference Include="ComponentAce.Compression.Libs.zlib">
<HintPath>..\PatchGenerator\References\ComponentAce.Compression.Libs.zlib.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

View File

@ -0,0 +1,13 @@
namespace PatcherUtils
{
/// <summary>
/// <see cref="WriteProgressHandler(object, int, int, int, string, string[])"/> delegate
/// </summary>
/// <param name="Sender">The object calling the handler</param>
/// <param name="Progress">The current number of items processed</param>
/// <param name="Total">The total number of items</param>
/// <param name="Percent">The percentage of items processed</param>
/// <param name="Message">An optional message to display above the progress bar</param>
/// <param name="AdditionalLineItems">Additional information to display below the progress bar.</param>
public delegate void ProgressChangedHandler(object Sender, int Progress, int Total, int Percent, string Message = "", params LineItem[] AdditionalLineItems);
}

View File

@ -0,0 +1,13 @@
using System;
using System.IO;
namespace PatcherUtils
{
public static class RandomExtensions
{
public static string FromCwd(this string s)
{
return Path.Combine(Environment.CurrentDirectory, s);
}
}
}

Binary file not shown.