Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,24 @@ jobs:
Write-Error "InputWeave.GameInput 套件 SHA256 不符。Expected=$expected Actual=$actual"
}

$expectedCommit = "72697db594b8f1863bd3fbf5db75ff69b40e3364"
$inspectDir = Join-Path $env:RUNNER_TEMP "inputweave-gameinput-package"
if (Test-Path $inspectDir) {
Remove-Item -LiteralPath $inspectDir -Recurse -Force
}
New-Item -ItemType Directory -Path $inspectDir | Out-Null
Expand-Archive -Path $packagePath -DestinationPath $inspectDir -Force
$nuspecPath = Get-ChildItem -LiteralPath $inspectDir -Filter "*.nuspec" -File | Select-Object -First 1
if ($null -eq $nuspecPath) {
Write-Error "InputWeave.GameInput 套件缺少 nuspec。"
}
$nuspecText = Get-Content -LiteralPath $nuspecPath.FullName -Raw
if ($nuspecText -notmatch "commit=`"$expectedCommit`"") {
Write-Error "InputWeave.GameInput 套件封裝來源 commit 不符;必須為 $expectedCommit。"
}

Write-Host "InputWeave.GameInput 套件 SHA256 驗證通過:$actual"
Write-Host "InputWeave.GameInput 套件封裝來源 commit 驗證通過:$expectedCommit"

- name: 還原主專案 NuGet 套件
run: dotnet restore ./src/InputBox/InputBox.csproj --force-evaluate
Expand Down
25 changes: 21 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,24 @@ jobs:
Write-Error "InputWeave.GameInput 套件 SHA256 不符。Expected=$expected Actual=$actual"
}

$expectedCommit = "72697db594b8f1863bd3fbf5db75ff69b40e3364"
$inspectDir = Join-Path $env:RUNNER_TEMP "inputweave-gameinput-package"
if (Test-Path $inspectDir) {
Remove-Item -LiteralPath $inspectDir -Recurse -Force
}
New-Item -ItemType Directory -Path $inspectDir | Out-Null
Expand-Archive -Path $packagePath -DestinationPath $inspectDir -Force
$nuspecPath = Get-ChildItem -LiteralPath $inspectDir -Filter "*.nuspec" -File | Select-Object -First 1
if ($null -eq $nuspecPath) {
Write-Error "InputWeave.GameInput 套件缺少 nuspec。"
}
$nuspecText = Get-Content -LiteralPath $nuspecPath.FullName -Raw
if ($nuspecText -notmatch "commit=`"$expectedCommit`"") {
Write-Error "InputWeave.GameInput 套件封裝來源 commit 不符;必須為 $expectedCommit。"
}

Write-Host "InputWeave.GameInput 套件 SHA256 驗證通過:$actual"
Write-Host "InputWeave.GameInput 套件封裝來源 commit 驗證通過:$expectedCommit"

- name: 還原 NuGet 套件
run: dotnet restore ./src/InputBox/InputBox.csproj --force-evaluate
Expand Down Expand Up @@ -237,13 +254,13 @@ jobs:
Add-Content -Path $noticePath -Encoding utf8 -Value '## InputWeave.GameInput'
Add-Content -Path $noticePath -Encoding utf8 -Value ''
Add-Content -Path $noticePath -Encoding utf8 -Value '- 套件:InputWeave.GameInput 0.0.1'
Add-Content -Path $noticePath -Encoding utf8 -Value '- 來源:https://github.com/rubujo/InputWeave.GameInput/tree/664a9d3e96458a49688ff2255a36f6e073977065'
Add-Content -Path $noticePath -Encoding utf8 -Value '- 來源:https://github.com/rubujo/InputWeave.GameInput/tree/72697db594b8f1863bd3fbf5db75ff69b40e3364'
Add-Content -Path $noticePath -Encoding utf8 -Value '- 作者:https://github.com/rubujo'
Add-Content -Path $noticePath -Encoding utf8 -Value '- 貢獻者:https://github.com/rubujo/InputWeave.GameInput/graphs/contributors'
Add-Content -Path $noticePath -Encoding utf8 -Value '- 封裝來源:https://github.com/rubujo/InputWeave.GameInput/commit/664a9d3e96458a49688ff2255a36f6e073977065'
Add-Content -Path $noticePath -Encoding utf8 -Value '- 封裝來源:https://github.com/rubujo/InputWeave.GameInput/commit/72697db594b8f1863bd3fbf5db75ff69b40e3364'
Add-Content -Path $noticePath -Encoding utf8 -Value '- 套件檔案:eng/nuget/InputWeave.GameInput.0.0.1.nupkg'
Add-Content -Path $noticePath -Encoding utf8 -Value '- SHA256: 64d9ef502853130d4af8df7cc1c2777a67808ef668e41c22fc6b526b83ed2805'
Add-Content -Path $noticePath -Encoding utf8 -Value '- 授權:Creative Commons CC0 1.0 Universal(SPDX:CC0-1.0);詳見本 Licenses 目錄中的 InputWeave.GameInput_LICENSE.txt 與 https://github.com/rubujo/InputWeave.GameInput/blob/664a9d3e96458a49688ff2255a36f6e073977065/LICENSE。'
Add-Content -Path $noticePath -Encoding utf8 -Value '- SHA256: 451b9d65143eafea130ec3492f12a991b29c62d53509e74b856894848f329f5e'
Add-Content -Path $noticePath -Encoding utf8 -Value '- 授權:Creative Commons CC0 1.0 Universal(SPDX:CC0-1.0);詳見本 Licenses 目錄中的 InputWeave.GameInput_LICENSE.txt 與 https://github.com/rubujo/InputWeave.GameInput/blob/72697db594b8f1863bd3fbf5db75ff69b40e3364/LICENSE。'

- name: 產生執行檔的雜湊值(SHA256)
shell: pwsh
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ Remove-Item Env:INPUTBOX_RUN_UI_TESTS -ErrorAction SilentlyContinue

- [.NET Runtime](https://github.com/dotnet/runtime):由 [Microsoft](https://github.com/microsoft) 及其 [貢獻者](https://github.com/dotnet/runtime/graphs/contributors) 開發並採用 [**MIT License**](https://github.com/dotnet/runtime/blob/main/LICENSE.TXT) 授權,作為本應用程式之底層執行環境,相關第三方聲明請參閱 [**THIRD-PARTY-NOTICES**](https://github.com/dotnet/runtime/blob/main/THIRD-PARTY-NOTICES.TXT)。
- [Windows Forms(WinForms)](https://github.com/dotnet/winforms):由 [Microsoft](https://github.com/microsoft) 及其 [貢獻者](https://github.com/dotnet/winforms/graphs/contributors) 開發並採用 [**MIT License**](https://github.com/dotnet/winforms/blob/main/LICENSE.TXT) 授權,提供桌面視窗圖形介面基礎架構,相關第三方聲明請參閱 [**THIRD-PARTY-NOTICES**](https://github.com/dotnet/winforms/blob/main/THIRD-PARTY-NOTICES.TXT)。
- [InputWeave.GameInput 0.0.1](https://github.com/rubujo/InputWeave.GameInput/tree/664a9d3e96458a49688ff2255a36f6e073977065):由 [rubujo](https://github.com/rubujo) 及其 [貢獻者](https://github.com/rubujo/InputWeave.GameInput/graphs/contributors) 開發並採用 [**CC0 1.0 Universal**](https://github.com/rubujo/InputWeave.GameInput/blob/664a9d3e96458a49688ff2255a36f6e073977065/LICENSE) 授權,提供 GameInput 執行階段、用戶端、裝置、讀取狀態與震動控制介面。套件固定於本儲存庫的 NuGet 來源 `eng/nuget/InputWeave.GameInput.0.0.1.nupkg`,封裝來源為 [`664a9d3e96458a49688ff2255a36f6e073977065`](https://github.com/rubujo/InputWeave.GameInput/commit/664a9d3e96458a49688ff2255a36f6e073977065),套件 SHA256 為 `64d9ef502853130d4af8df7cc1c2777a67808ef668e41c22fc6b526b83ed2805`。
- [InputWeave.GameInput 0.0.1](https://github.com/rubujo/InputWeave.GameInput/tree/72697db594b8f1863bd3fbf5db75ff69b40e3364):由 [rubujo](https://github.com/rubujo) 及其 [貢獻者](https://github.com/rubujo/InputWeave.GameInput/graphs/contributors) 開發並採用 [**CC0 1.0 Universal**](https://github.com/rubujo/InputWeave.GameInput/blob/72697db594b8f1863bd3fbf5db75ff69b40e3364/LICENSE) 授權,提供 GameInput 執行階段、用戶端、裝置、讀取狀態與震動控制介面。套件固定於本儲存庫的 NuGet 來源 `eng/nuget/InputWeave.GameInput.0.0.1.nupkg`,封裝來源為 [`72697db594b8f1863bd3fbf5db75ff69b40e3364`](https://github.com/rubujo/InputWeave.GameInput/commit/72697db594b8f1863bd3fbf5db75ff69b40e3364),套件 SHA256 為 `451b9d65143eafea130ec3492f12a991b29c62d53509e74b856894848f329f5e`。
- [Microsoft GameInput Redistributable](https://www.nuget.org/packages/Microsoft.GameInput):由 Microsoft 提供,作為選用的 GameInput 執行階段可轉散發套件。正式發佈 ZIP 檔會隨附 `redist/GameInputRedist.msi` 供使用者手動安裝;本應用程式不會自動安裝。手動安裝 `redist/GameInputRedist.msi` 即表示使用者需遵守 [Microsoft.GameInput 授權條款](https://www.nuget.org/packages/Microsoft.GameInput/3.4.218/License);相關授權與 NOTICE 檔案位於 `Licenses/Microsoft.GameInput_LICENSE.txt` 與 `Licenses/Microsoft.GameInput_NOTICE.txt`,且該可轉散發安裝程式不屬於本專案 CC0 授權範圍。

本專案的詳細條款與免責聲明,請參閱隨附之 [**LICENSE**](LICENSE) 文件;發佈檔 `Licenses/` 資料夾內含 `ThirdPartyNotices.txt`(NuGet 套件授權聲明清單)、`InputWeave.GameInput_LICENSE.txt`、`Microsoft.GameInput_LICENSE.txt`、`Microsoft.GameInput_NOTICE.txt`,以及各元件完整授權文字;[Microsoft.GameInput 3.4.218 線上授權頁](https://www.nuget.org/packages/Microsoft.GameInput/3.4.218/License) 另可於 NuGet 查閱。
1 change: 1 addition & 0 deletions docs/engineering/gamepad-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
- **GameInput 同步**:InputBox 仍必須在背景 MTA polling thread 建立、存取與釋放 InputWeave `GameInputClient` / `GameInputDevice` / callback registration;callback 只能設定喚醒或重新整理訊號,不得直接觸發 managed UI 命令。
- **GameInput 診斷 metadata 邊界**:runtime probe、timestamp stale counters、missing reading counters、device unavailable refresh counters 只能進入 log、測試或未來診斷快照,不可直接改變 edge detection、Pause/Resume neutral gate 或任何 UI 命令。
- **GameInput subset 範圍**:目前只實作 InputBox 需要的 Gamepad subset:裝置資訊、VID/PID、timestamp、gamepad button state、rumble、device/reading callbacks,以及 gamepad capabilities / extra control metadata。不得在未重新評估安全與產品需求前擴張到 keyboard、mouse、sensors、raw report、force feedback、aggregate device 或 1:1 GameInput wrapper。
- **InputWeave callback 互通性**:repo-local `InputWeave.GameInput` 套件的 `IGameInput.Register*Callback` callback 參數必須以 `MarshalAs(UnmanagedType.FunctionPtr)` 宣告。不得以 InputBox 端 aggregate polling fallback 遮蔽 callback marshaling 錯誤;若列舉或 callback 仍失敗,應走既有 GameInput 初始化失敗與 XInput 退避路徑。
- **Callback 使用邊界**:GameInput 的 `RegisterDeviceCallback` / `RegisterReadingCallback` 僅可用於要求背景 MTA polling thread 重新整理或喚醒診斷路徑;正式輸入命令仍必須由 60 FPS polling 消費,callback 不得直接觸發 UI、剪貼簿、返回前景或任何輸入動作。
- **GameInput runtime/redist 政策**:`Microsoft.GameInput` NuGet 僅作為官方 SDK、header 與 redist 來源。發佈 ZIP 可隨附 `redist/GameInputRedist.msi` 供使用者手動安裝,但應用程式不得自動執行安裝程式,也不得要求一般啟動流程取得系統管理員權限。
- **Auto 模式解析優先序**:當使用者選擇 Face 鍵 `Auto` 模式且目前提供者為 **GameInput** 時,必須先使用較穩定的硬體識別資訊(例如 VID/PID、產品家族名稱)判斷裝置類型,再退回裝置名稱關鍵字比對;像 `Wireless`、`Bluetooth`、`Adapter`、`Receiver` 等連線詞應視為雜訊而忽略。
Expand Down
Binary file modified eng/nuget/InputWeave.GameInput.0.0.1.nupkg
Binary file not shown.
2 changes: 1 addition & 1 deletion eng/nuget/InputWeave.GameInput.0.0.1.nupkg.sha256
Original file line number Diff line number Diff line change
@@ -1 +1 @@
64d9ef502853130d4af8df7cc1c2777a67808ef668e41c22fc6b526b83ed2805 InputWeave.GameInput.0.0.1.nupkg
451b9d65143eafea130ec3492f12a991b29c62d53509e74b856894848f329f5e InputWeave.GameInput.0.0.1.nupkg
8 changes: 4 additions & 4 deletions eng/nuget/InputWeave.GameInput_LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
InputWeave.GameInput 0.0.1
===========================

來源: https://github.com/rubujo/InputWeave.GameInput/tree/664a9d3e96458a49688ff2255a36f6e073977065
來源: https://github.com/rubujo/InputWeave.GameInput/tree/72697db594b8f1863bd3fbf5db75ff69b40e3364
作者: https://github.com/rubujo
貢獻者: https://github.com/rubujo/InputWeave.GameInput/graphs/contributors
封裝來源: https://github.com/rubujo/InputWeave.GameInput/commit/664a9d3e96458a49688ff2255a36f6e073977065
封裝來源: https://github.com/rubujo/InputWeave.GameInput/commit/72697db594b8f1863bd3fbf5db75ff69b40e3364
套件檔案: eng/nuget/InputWeave.GameInput.0.0.1.nupkg
套件 SHA256: 64d9ef502853130d4af8df7cc1c2777a67808ef668e41c22fc6b526b83ed2805
套件 SHA256: 451b9d65143eafea130ec3492f12a991b29c62d53509e74b856894848f329f5e
授權名稱: Creative Commons CC0 1.0 Universal
授權識別碼 (SPDX): CC0-1.0
授權檔案: https://github.com/rubujo/InputWeave.GameInput/blob/664a9d3e96458a49688ff2255a36f6e073977065/LICENSE
授權檔案: https://github.com/rubujo/InputWeave.GameInput/blob/72697db594b8f1863bd3fbf5db75ff69b40e3364/LICENSE

InputWeave.GameInput 採用 Creative Commons CC0 1.0 Universal 公眾領域貢獻宣告。
在法律允許的最大範圍內,作者已將此套件的著作權與相關權利貢獻至全球公眾領域。
Expand Down
24 changes: 24 additions & 0 deletions tests/InputBox.Tests/GameInputDirectUsageTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using InputWeave.GameInput;
using InputWeave.GameInput.Interop;
using System.Reflection;
using System.Runtime.InteropServices;
using Xunit;

namespace InputBox.Tests;
Expand Down Expand Up @@ -30,6 +31,18 @@ public void RequiredInputWeaveGamepadApi_Surface_IsAvailable()
Assert.NotNull(typeof(GameInputDevice).GetMethod(nameof(GameInputDevice.SetRumbleState), [typeof(GameInputRumbleParams).MakeByRefType()]));
}

/// <summary>
/// InputWeave 的 GameInput callback 參數必須以 unmanaged function pointer 傳遞,避免退回 _Delegate COM marshaling。
/// </summary>
[Fact]
public void GameInputCallbackParameters_AreFunctionPointers()
{
AssertCallbackParameterIsFunctionPointer(nameof(IGameInput.RegisterReadingCallback), typeof(GameInputReadingCallback));
AssertCallbackParameterIsFunctionPointer(nameof(IGameInput.RegisterDeviceCallback), typeof(GameInputDeviceCallback));
AssertCallbackParameterIsFunctionPointer(nameof(IGameInput.RegisterSystemButtonCallback), typeof(GameInputSystemButtonCallback));
AssertCallbackParameterIsFunctionPointer(nameof(IGameInput.RegisterKeyboardLayoutCallback), typeof(GameInputKeyboardLayoutCallback));
}

/// <summary>
/// GameInput v3 的 gamepad button 位元必須維持 Microsoft 定義值,避免 face key、D-Pad、背鍵與搖桿方向判斷錯位。
/// </summary>
Expand Down Expand Up @@ -166,6 +179,17 @@ public void GameInputRumbleParams_MotorFields_PreserveAssignedValues()
Assert.Equal(0.4f, rumble.RightTrigger);
}

private static void AssertCallbackParameterIsFunctionPointer(string methodName, Type callbackType)
{
MethodInfo method = typeof(IGameInput).GetMethod(methodName)
?? throw new InvalidOperationException($"找不到 IGameInput.{methodName}。");
ParameterInfo callbackParameter = method.GetParameters().Single(parameter => parameter.ParameterType == callbackType);
MarshalAsAttribute? marshalAs = callbackParameter.GetCustomAttribute<MarshalAsAttribute>();

Assert.NotNull(marshalAs);
Assert.Equal(UnmanagedType.FunctionPtr, marshalAs.Value);
}

private static GameInputDeviceInfoSnapshot CreateDeviceInfoSnapshot(
ushort vendorId,
ushort productId,
Expand Down
6 changes: 3 additions & 3 deletions tests/InputBox.Tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
| `GamepadDeadzoneHysteresisTests` | `GamepadDeadzoneHysteresis.ResolveDirection`(int / float 多載),含正負方向對稱性守門(硬體平等原則) | 14 |
| `GamepadControllerFactoryTests` | 控制器後端建立策略,驗證 XInput 預設路徑、GameInput 成功路徑,以及 GameInput 執行階段不可用時退避至 XInput | 3 |
| `GamepadControllerPauseTests` | 控制器在 `Pause()` / `Resume()`、連線可用性語意、GameInput 讀取缺失斷線重列舉、裝置狀態過濾、震動停止安全性、`ClearAllEvents` 肩鍵釋放訂閱清除與原生對話框切換時的殘留輸入回歸保護 | 10 |
| `GameInputDirectUsageTests` | `GameInputGamepadController` 直接使用 `InputWeave.GameInput` 遊戲控制器介面的守門、官方 v3 按鍵位元、快照邊緣偵測、穩定裝置識別與震動參數保留 | 7 |
| `GameInputDirectUsageTests` | `GameInputGamepadController` 直接使用 `InputWeave.GameInput` 遊戲控制器介面的守門、callback function pointer marshaling、官方 v3 按鍵位元、快照邊緣偵測、穩定裝置識別與震動參數保留 | 8 |
| `GamepadCalibrationVisualizerMapperTests` | `GamepadCalibrationVisualizerMapper` 對校準視覺化座標限制、死區半徑換算、D-Pad 導覽防誤觸,以及雙搖桿狀態/控制器連線文案格式化的回歸保護 | 14 |
| `GamepadEventBinderTests` | `GamepadEventBinder` 的 LB / RB / LT / RT 與肩鍵放開事件綁定回歸保護 | 1 |
| `GamepadFaceButtonProfileTests` | `GamepadFaceButtonProfile` 的 Auto 解析、手動覆寫優先權、GameInput 裝置識別保留 VID/PID 時的 Sony/Nintendo 判斷,以及 Xbox / PlayStation / Nintendo 模式的按鍵標示、助記詞同步、資源化字串、主畫面說明文字、目前生效配置顯示、標題列提示、選單勾選邏輯與 PlayStation ○/× 確認模式回歸保護 | 25 |
Expand All @@ -45,7 +45,7 @@
| `TaskExtensionsTests` | `TaskExtensions` CTS 擴充方法與生命週期連結保護 | 12 |
| `VibrationPatternsTests` | `VibrationPatterns` 與方向性震動設定、語意情境解析、能力感知的多段式微震動序列,以及歷程滾輪阻尼感、字數上限硬牆、震動強度預覽、右搖桿選取粒度、組合鍵進入提示與喚起握手回饋的回歸保護 | 37 |
| `VibrationSafetyLimiterTests` | `VibrationSafetyLimiter` 熱保護、Duty Cycle 限制器與極端邊界保護 | 8 |
| **合計** | | **383** |
| **合計** | | **384** |

## 二、執行方式 🚀

Expand Down Expand Up @@ -121,7 +121,7 @@ xUnit v3 為每個 `[Fact]` 建立獨立的測試類別實例,`IDisposable.Dis
- Microsoft.Testing.Extensions.CodeCoverage:原始碼儲存庫為 [microsoft/codecoverage](https://github.com/microsoft/codecoverage),由 [Microsoft](https://github.com/microsoft) 及其 [貢獻者](https://github.com/microsoft/codecoverage/graphs/contributors) 開發並採用 [MIT License](https://github.com/microsoft/codecoverage/blob/main/LICENSE) 授權,用於測試覆蓋率收集。
- FlaUI.Core:原始碼儲存庫為 [FlaUI/FlaUI](https://github.com/FlaUI/FlaUI),由 [Roman Baeriswyl](https://github.com/Roemer) 及其 [貢獻者](https://github.com/FlaUI/FlaUI/graphs/contributors) 開發並採用 [MIT License](https://github.com/FlaUI/FlaUI/blob/main/LICENSE.txt) 授權,作為 Windows UI 自動化核心函式庫。
- FlaUI.UIA3:原始碼儲存庫為 [FlaUI/FlaUI](https://github.com/FlaUI/FlaUI),由 [Roman Baeriswyl](https://github.com/Roemer) 及其 [貢獻者](https://github.com/FlaUI/FlaUI/graphs/contributors) 開發並採用 [MIT License](https://github.com/FlaUI/FlaUI/blob/main/LICENSE.txt) 授權,作為 UIA3 後端,用於 WinForms UI 冒煙測試。
- InputWeave.GameInput 0.0.1:原始碼儲存庫固定於 [rubujo/InputWeave.GameInput 封裝來源](https://github.com/rubujo/InputWeave.GameInput/tree/664a9d3e96458a49688ff2255a36f6e073977065),由 [rubujo](https://github.com/rubujo) 及其 [貢獻者](https://github.com/rubujo/InputWeave.GameInput/graphs/contributors) 開發並採用 [CC0 1.0 Universal](https://github.com/rubujo/InputWeave.GameInput/blob/664a9d3e96458a49688ff2255a36f6e073977065/LICENSE) 授權,作為 GameInput 直接使用與震動型別守門測試依賴;套件固定於 [../../eng/nuget/InputWeave.GameInput.0.0.1.nupkg](../../eng/nuget/InputWeave.GameInput.0.0.1.nupkg),SHA256 為 `64d9ef502853130d4af8df7cc1c2777a67808ef668e41c22fc6b526b83ed2805`。
- InputWeave.GameInput 0.0.1:原始碼儲存庫固定於 [rubujo/InputWeave.GameInput 封裝來源](https://github.com/rubujo/InputWeave.GameInput/tree/72697db594b8f1863bd3fbf5db75ff69b40e3364),由 [rubujo](https://github.com/rubujo) 及其 [貢獻者](https://github.com/rubujo/InputWeave.GameInput/graphs/contributors) 開發並採用 [CC0 1.0 Universal](https://github.com/rubujo/InputWeave.GameInput/blob/72697db594b8f1863bd3fbf5db75ff69b40e3364/LICENSE) 授權,作為 GameInput 直接使用與震動型別守門測試依賴;套件固定於 [../../eng/nuget/InputWeave.GameInput.0.0.1.nupkg](../../eng/nuget/InputWeave.GameInput.0.0.1.nupkg),SHA256 為 `451b9d65143eafea130ec3492f12a991b29c62d53509e74b856894848f329f5e`。

本測試專案的相關說明詳見本文件;主專案授權與完整聲明仍以 [../../README.md](../../README.md) 及 [../../LICENSE](../../LICENSE) 為準。

Expand Down
Loading