diff --git a/.gitignore b/.gitignore
index 1aa9465..8909666 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,11 @@
################################################################################
/.vs/ViGEmBus/v15
+/build/bin/Release
+/build/obj/Release
+/lib/x64
+/packages
+/sys/x64/Release
+/x64/Release
+/x64/Release (dynamic)
+/x64/Release (static)
diff --git a/.nuke b/.nuke
new file mode 100644
index 0000000..1256cc3
Binary files /dev/null and b/.nuke differ
diff --git a/ViGEmBus.sln b/ViGEmBus.sln
index 1a83c0f..a3b3627 100644
--- a/ViGEmBus.sln
+++ b/ViGEmBus.sln
@@ -3,6 +3,8 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2024
MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = ".build", "build\.build.csproj", "{6DAE6010-3A66-4191-B462-60E82A0D0445}"
+EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ViGEmBus", "sys\ViGEmBus.vcxproj", "{040101B0-EE5C-4EF1-99EE-9F81C795C001}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ViGEmClient", "lib\ViGEmClient.vcxproj", "{7DB06674-1F4F-464B-8E1C-172E9587F9DC}"
@@ -35,6 +37,54 @@ Global
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Debug (dynamic)|ARM.ActiveCfg = Debug|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Debug (dynamic)|ARM.Build.0 = Debug|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Debug (dynamic)|ARM64.ActiveCfg = Debug|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Debug (dynamic)|ARM64.Build.0 = Debug|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Debug (dynamic)|x64.ActiveCfg = Debug|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Debug (dynamic)|x64.Build.0 = Debug|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Debug (dynamic)|x86.ActiveCfg = Debug|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Debug (dynamic)|x86.Build.0 = Debug|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Debug (static)|ARM.ActiveCfg = Debug|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Debug (static)|ARM.Build.0 = Debug|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Debug (static)|ARM64.ActiveCfg = Debug|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Debug (static)|ARM64.Build.0 = Debug|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Debug (static)|x64.ActiveCfg = Debug|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Debug (static)|x64.Build.0 = Debug|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Debug (static)|x86.ActiveCfg = Debug|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Debug (static)|x86.Build.0 = Debug|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Debug|ARM.Build.0 = Debug|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Debug|ARM64.ActiveCfg = Debug|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Debug|ARM64.Build.0 = Debug|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Debug|x64.Build.0 = Debug|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Debug|x86.Build.0 = Debug|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Release (dynamic)|ARM.ActiveCfg = Release|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Release (dynamic)|ARM.Build.0 = Release|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Release (dynamic)|ARM64.ActiveCfg = Release|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Release (dynamic)|ARM64.Build.0 = Release|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Release (dynamic)|x64.ActiveCfg = Release|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Release (dynamic)|x64.Build.0 = Release|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Release (dynamic)|x86.ActiveCfg = Release|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Release (dynamic)|x86.Build.0 = Release|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Release (static)|ARM.ActiveCfg = Release|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Release (static)|ARM.Build.0 = Release|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Release (static)|ARM64.ActiveCfg = Release|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Release (static)|ARM64.Build.0 = Release|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Release (static)|x64.ActiveCfg = Release|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Release (static)|x64.Build.0 = Release|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Release (static)|x86.ActiveCfg = Release|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Release (static)|x86.Build.0 = Release|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Release|ARM.ActiveCfg = Release|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Release|ARM.Build.0 = Release|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Release|ARM64.ActiveCfg = Release|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Release|ARM64.Build.0 = Release|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Release|x64.ActiveCfg = Release|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Release|x64.Build.0 = Release|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Release|x86.ActiveCfg = Release|Any CPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}.Release|x86.Build.0 = Release|Any CPU
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug (dynamic)|ARM.ActiveCfg = Debug|ARM
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug (dynamic)|ARM.Build.0 = Debug|ARM
{040101B0-EE5C-4EF1-99EE-9F81C795C001}.Debug (dynamic)|ARM.Deploy.0 = Debug|ARM
diff --git a/build.ps1 b/build.ps1
new file mode 100644
index 0000000..ec371c0
--- /dev/null
+++ b/build.ps1
@@ -0,0 +1,52 @@
+[CmdletBinding()]
+Param(
+ [switch]$NoInit,
+ [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)]
+ [string[]]$BuildArguments
+)
+
+Set-StrictMode -Version 2.0; $ErrorActionPreference = "Stop"; $ConfirmPreference = "None"; trap { $host.SetShouldExit(1) }
+$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
+
+###########################################################################
+# CONFIGURATION
+###########################################################################
+
+$NuGetVersion = "latest"
+$SolutionDirectory = "$PSScriptRoot\..\ViGEm"
+$BuildProjectFile = "$PSScriptRoot\.\build\.build.csproj"
+$BuildExeFile = "$PSScriptRoot\.\build\bin\debug\.build.exe"
+
+$TempDirectory = "$PSScriptRoot\.tmp"
+
+$NuGetUrl = "https://dist.nuget.org/win-x86-commandline/$NuGetVersion/nuget.exe"
+$NuGetFile = "$TempDirectory\nuget.exe"
+$env:NUGET_EXE = $NuGetFile
+
+###########################################################################
+# PREPARE BUILD
+###########################################################################
+
+function ExecSafe([scriptblock] $cmd) {
+ & $cmd
+ if ($LastExitCode -ne 0) { throw "The following call failed with exit code $LastExitCode. '$cmd'" }
+}
+
+if (!$NoInit) {
+ md -force $TempDirectory > $null
+
+ if (!(Test-Path $NuGetFile)) { (New-Object System.Net.WebClient).DownloadFile($NuGetUrl, $NuGetFile) }
+ elseif ($NuGetVersion -eq "latest") { & $NuGetFile update -Self }
+
+ ExecSafe { & $NuGetFile restore $BuildProjectFile -SolutionDirectory $SolutionDirectory }
+ ExecSafe { & $NuGetFile install Nuke.MSBuildLocator -ExcludeVersion -OutputDirectory $TempDirectory -SolutionDirectory $SolutionDirectory }
+}
+
+$MSBuildFile = & "$TempDirectory\Nuke.MSBuildLocator\tools\Nuke.MSBuildLocator.exe"
+ExecSafe { & $MSBuildFile $BuildProjectFile }
+
+###########################################################################
+# EXECUTE BUILD
+###########################################################################
+
+ExecSafe { & $BuildExeFile $BuildArguments }
diff --git a/build.sh b/build.sh
new file mode 100644
index 0000000..c5d8219
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,50 @@
+#!/usr/bin/env bash
+
+NOINIT=0
+BUILD_ARGUMENTS=()
+for i in "$@"; do
+ case $(echo $1 | awk '{print tolower($0)}') in
+ -noinit) NOINIT=1;;
+ *) BUILD_ARGUMENTS+=("$1") ;;
+ esac
+ shift
+done
+
+set -eo pipefail
+SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)
+
+###########################################################################
+# CONFIGURATION
+###########################################################################
+
+NUGET_VERSION="latest"
+SOLUTION_DIRECTORY="$SCRIPT_DIR/../ViGEm"
+BUILD_PROJECT_FILE="$SCRIPT_DIR/./build/.build.csproj"
+BUILD_EXE_FILE="$SCRIPT_DIR/./build/bin/Debug/.build.exe"
+
+TEMP_DIRECTORY="$SCRIPT_DIR/.tmp"
+
+NUGET_URL="https://dist.nuget.org/win-x86-commandline/$NUGET_VERSION/nuget.exe"
+NUGET_FILE="$TEMP_DIRECTORY/nuget.exe"
+export NUGET_EXE="$NUGET_FILE"
+
+###########################################################################
+# PREPARE BUILD
+###########################################################################
+
+if ! ((NOINIT)); then
+ mkdir -p "$TEMP_DIRECTORY"
+
+ if [ ! -f "$NUGET_FILE" ]; then curl -Lsfo "$NUGET_FILE" $NUGET_URL;
+ elif [ $NUGET_VERSION == "latest" ]; then mono "$NUGET_FILE" update -Self; fi
+
+ mono "$NUGET_FILE" restore "$BUILD_PROJECT_FILE" -SolutionDirectory $SOLUTION_DIRECTORY
+fi
+
+msbuild "$BUILD_PROJECT_FILE"
+
+###########################################################################
+# EXECUTE BUILD
+###########################################################################
+
+mono "$BUILD_EXE_FILE" ${BUILD_ARGUMENTS[@]}
diff --git a/build/.build.csproj b/build/.build.csproj
new file mode 100644
index 0000000..6c96206
--- /dev/null
+++ b/build/.build.csproj
@@ -0,0 +1,128 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {6DAE6010-3A66-4191-B462-60E82A0D0445}
+ Exe
+
+ .build
+ v4.6.1
+ 512
+ true
+
+ CS0649;CS0169
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\..\ViGEm\packages\AutoMapper.6.0.2\lib\net45\AutoMapper.dll
+
+
+ ..\..\ViGEm\packages\Colorful.Console.1.0.7\lib\net461\Colorful.Console.dll
+
+
+ ..\..\ViGEm\packages\Glob.0.3.2\lib\net46\Glob.dll
+
+
+ ..\..\ViGEm\packages\JetBrains.Annotations.10.4.0\lib\net\JetBrains.Annotations.dll
+
+
+ ..\..\ViGEm\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll
+
+
+ ..\..\ViGEm\packages\Newtonsoft.Json.Bson.1.0.1\lib\net45\Newtonsoft.Json.Bson.dll
+
+
+ ..\..\ViGEm\packages\NuGet.Client.4.0.0\lib\net45\NuGet.Client.dll
+
+
+ ..\..\ViGEm\packages\NuGet.Common.4.0.0\lib\net45\NuGet.Common.dll
+
+
+ ..\..\ViGEm\packages\NuGet.ContentModel.4.0.0\lib\net45\NuGet.ContentModel.dll
+
+
+ ..\..\ViGEm\packages\NuGet.Frameworks.4.0.0\lib\net45\NuGet.Frameworks.dll
+
+
+ ..\..\ViGEm\packages\NuGet.Packaging.4.0.0\lib\net45\NuGet.Packaging.dll
+
+
+ ..\..\ViGEm\packages\NuGet.Packaging.Core.4.0.0\lib\net45\NuGet.Packaging.Core.dll
+
+
+ ..\..\ViGEm\packages\NuGet.Packaging.Core.Types.4.0.0\lib\net45\NuGet.Packaging.Core.Types.dll
+
+
+ ..\..\ViGEm\packages\NuGet.Repositories.4.0.0\lib\net45\NuGet.Repositories.dll
+
+
+ ..\..\ViGEm\packages\NuGet.RuntimeModel.4.0.0\lib\net45\NuGet.RuntimeModel.dll
+
+
+ ..\..\ViGEm\packages\NuGet.Versioning.4.0.0\lib\net45\NuGet.Versioning.dll
+
+
+ ..\..\ViGEm\packages\Nuke.Common.0.1.458\lib\net461\Nuke.Common.dll
+
+
+ ..\..\ViGEm\packages\Nuke.Core.0.1.458\lib\net461\Nuke.Core.dll
+
+
+ ..\..\ViGEm\packages\Octokit.0.24.0\lib\net45\Octokit.dll
+
+
+
+
+ ..\..\ViGEm\packages\System.Diagnostics.Process.4.3.0\lib\net461\System.Diagnostics.Process.dll
+
+
+
+
+
+ ..\..\ViGEm\packages\System.Runtime.Serialization.Formatters.4.3.0\lib\net46\System.Runtime.Serialization.Formatters.dll
+
+
+ ..\..\ViGEm\packages\System.Runtime.Serialization.Primitives.4.3.0\lib\net46\System.Runtime.Serialization.Primitives.dll
+
+
+ ..\..\ViGEm\packages\System.ValueTuple.4.3.0\lib\netstandard1.0\System.ValueTuple.dll
+
+
+
+
+
+
+
+
+ ..\..\ViGEm\packages\YamlDotNet.4.2.1\lib\net35\YamlDotNet.dll
+
+
+
+
+
+
+
+
+
+
diff --git a/build/.build.csproj.dotsettings b/build/.build.csproj.dotsettings
new file mode 100644
index 0000000..de07a95
--- /dev/null
+++ b/build/.build.csproj.dotsettings
@@ -0,0 +1,17 @@
+
+ False
+ Implicit
+ Implicit
+ ExpressionBody
+ 0
+ NEXT_LINE
+ True
+ False
+ WRAP_IF_LONG
+ True
+ False
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ True
+ True
+ True
diff --git a/build/Build.cs b/build/Build.cs
new file mode 100644
index 0000000..2cd6b2f
--- /dev/null
+++ b/build/Build.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Linq;
+using Nuke.Common;
+using Nuke.Common.Git;
+using Nuke.Common.Tools.GitVersion;
+using Nuke.Common.Tools.MSBuild;
+using Nuke.Core;
+using static Nuke.Common.Tools.MSBuild.MSBuildTasks;
+using static Nuke.Core.IO.FileSystemTasks;
+using static Nuke.Core.IO.PathConstruction;
+using static Nuke.Core.EnvironmentInfo;
+
+class Build : NukeBuild
+{
+ // Console application entry. Also defines the default target.
+ public static int Main () => Execute(x => x.Compile);
+
+ // Auto-injection fields:
+
+ // [GitVersion] readonly GitVersion GitVersion;
+ // Semantic versioning. Must have 'GitVersion.CommandLine' referenced.
+
+ // [GitRepository] readonly GitRepository GitRepository;
+ // Parses origin, branch name and head from git config.
+
+ // [Parameter] readonly string MyGetApiKey;
+ // Returns command-line arguments and environment variables.
+
+ Target Clean => _ => _
+ .OnlyWhen(() => false) // Disabled for safety.
+ .Executes(() =>
+ {
+ DeleteDirectories(GlobDirectories(SourceDirectory, "**/bin", "**/obj"));
+ EnsureCleanDirectory(OutputDirectory);
+ });
+
+ Target Restore => _ => _
+ .DependsOn(Clean)
+ .Executes(() =>
+ {
+ MSBuild(s => DefaultMSBuildRestore.SetTargetPlatform(MSBuildTargetPlatform.x64));
+ MSBuild(s => DefaultMSBuildRestore.SetTargetPlatform(MSBuildTargetPlatform.x86));
+ });
+
+ Target Compile => _ => _
+ .DependsOn(Restore)
+ .Executes(() =>
+ {
+ MSBuild(s => DefaultMSBuildCompile.SetTargetPlatform(MSBuildTargetPlatform.x64));
+ MSBuild(s => DefaultMSBuildCompile.SetTargetPlatform(MSBuildTargetPlatform.x86));
+ });
+}
diff --git a/build/packages.config b/build/packages.config
new file mode 100644
index 0000000..491a6ea
--- /dev/null
+++ b/build/packages.config
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+