diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 7812be5..924250a 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -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
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index ad6318b..0b95a22 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -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
@@ -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
diff --git a/README.md b/README.md
index 55cdf3d..95aa536 100644
--- a/README.md
+++ b/README.md
@@ -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 查閱。
diff --git a/docs/engineering/gamepad-api.md b/docs/engineering/gamepad-api.md
index 15932eb..96b8538 100644
--- a/docs/engineering/gamepad-api.md
+++ b/docs/engineering/gamepad-api.md
@@ -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` 等連線詞應視為雜訊而忽略。
diff --git a/eng/nuget/InputWeave.GameInput.0.0.1.nupkg b/eng/nuget/InputWeave.GameInput.0.0.1.nupkg
index da3d81e..cc95516 100644
Binary files a/eng/nuget/InputWeave.GameInput.0.0.1.nupkg and b/eng/nuget/InputWeave.GameInput.0.0.1.nupkg differ
diff --git a/eng/nuget/InputWeave.GameInput.0.0.1.nupkg.sha256 b/eng/nuget/InputWeave.GameInput.0.0.1.nupkg.sha256
index ee5c8d7..14d0220 100644
--- a/eng/nuget/InputWeave.GameInput.0.0.1.nupkg.sha256
+++ b/eng/nuget/InputWeave.GameInput.0.0.1.nupkg.sha256
@@ -1 +1 @@
-64d9ef502853130d4af8df7cc1c2777a67808ef668e41c22fc6b526b83ed2805 InputWeave.GameInput.0.0.1.nupkg
+451b9d65143eafea130ec3492f12a991b29c62d53509e74b856894848f329f5e InputWeave.GameInput.0.0.1.nupkg
diff --git a/eng/nuget/InputWeave.GameInput_LICENSE.txt b/eng/nuget/InputWeave.GameInput_LICENSE.txt
index 66fddfe..d300119 100644
--- a/eng/nuget/InputWeave.GameInput_LICENSE.txt
+++ b/eng/nuget/InputWeave.GameInput_LICENSE.txt
@@ -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 公眾領域貢獻宣告。
在法律允許的最大範圍內,作者已將此套件的著作權與相關權利貢獻至全球公眾領域。
diff --git a/tests/InputBox.Tests/GameInputDirectUsageTests.cs b/tests/InputBox.Tests/GameInputDirectUsageTests.cs
index 68f6c49..77330a2 100644
--- a/tests/InputBox.Tests/GameInputDirectUsageTests.cs
+++ b/tests/InputBox.Tests/GameInputDirectUsageTests.cs
@@ -2,6 +2,7 @@
using InputWeave.GameInput;
using InputWeave.GameInput.Interop;
using System.Reflection;
+using System.Runtime.InteropServices;
using Xunit;
namespace InputBox.Tests;
@@ -30,6 +31,18 @@ public void RequiredInputWeaveGamepadApi_Surface_IsAvailable()
Assert.NotNull(typeof(GameInputDevice).GetMethod(nameof(GameInputDevice.SetRumbleState), [typeof(GameInputRumbleParams).MakeByRefType()]));
}
+ ///
+ /// InputWeave 的 GameInput callback 參數必須以 unmanaged function pointer 傳遞,避免退回 _Delegate COM marshaling。
+ ///
+ [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));
+ }
+
///
/// GameInput v3 的 gamepad button 位元必須維持 Microsoft 定義值,避免 face key、D-Pad、背鍵與搖桿方向判斷錯位。
///
@@ -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();
+
+ Assert.NotNull(marshalAs);
+ Assert.Equal(UnmanagedType.FunctionPtr, marshalAs.Value);
+ }
+
private static GameInputDeviceInfoSnapshot CreateDeviceInfoSnapshot(
ushort vendorId,
ushort productId,
diff --git a/tests/InputBox.Tests/README.md b/tests/InputBox.Tests/README.md
index 4e396ff..dfae4a2 100644
--- a/tests/InputBox.Tests/README.md
+++ b/tests/InputBox.Tests/README.md
@@ -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 |
@@ -45,7 +45,7 @@
| `TaskExtensionsTests` | `TaskExtensions` CTS 擴充方法與生命週期連結保護 | 12 |
| `VibrationPatternsTests` | `VibrationPatterns` 與方向性震動設定、語意情境解析、能力感知的多段式微震動序列,以及歷程滾輪阻尼感、字數上限硬牆、震動強度預覽、右搖桿選取粒度、組合鍵進入提示與喚起握手回饋的回歸保護 | 37 |
| `VibrationSafetyLimiterTests` | `VibrationSafetyLimiter` 熱保護、Duty Cycle 限制器與極端邊界保護 | 8 |
-| **合計** | | **383** |
+| **合計** | | **384** |
## 二、執行方式 🚀
@@ -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) 為準。