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
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion src/device/controller.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -118,6 +118,7 @@ import { FinalmouseHidClient } from "@openmouse/protocol/drivers/finalmouse/hid"
import { ModdoHidClient } from "@openmouse/protocol/drivers/moddo/hid";
import { NinjutsoHidClient } from "@openmouse/protocol/drivers/ninjutso/hid";
import { ZaunkoenigHidClient } from "@openmouse/protocol/drivers/zaunkoenig/hid";
import { CorsairHidClient } from "@openmouse/protocol/drivers/corsair/hid";
import { TeevolutionHidClient } from "@openmouse/protocol/drivers/teevolution/hid";
import { teevolutionProfileForCid } from "@openmouse/protocol/teevolution";
import { VgnF2HidClient } from "@openmouse/protocol/drivers/vgn/hid";
Expand DownExpand Up@@ -197,7 +198,7 @@ function activeAs<T>(...classes: ClientClass<T>[]): T | null {

const DM_CLASSES = [WLMouseHidClient, LamzuHidClient, AtkHidClient, AtkBitmouseHidClient, NinjutsoHidClient] as const;
const RAZER_CLASSES = [RazerHidClient, RazerViperMiniHidClient, RazerViperHidClient, RazerCobraHidClient] as const;
const NEEDS_OPEN = [TeevolutionHidClient, VgnF2HidClient, KeychronNapeHidClient, KeychronM6HidClient, ModdoHidClient, ZaunkoenigHidClient, FantechHidClient, WallhackMouseHidClient, WallhackKeyboardHidClient, GloriousHidClient, GloriousClassicHidClient, MchoseHidClient, MchoseDockHidClient, MicrosoftHidClient] as const;
const NEEDS_OPEN = [TeevolutionHidClient, VgnF2HidClient, KeychronNapeHidClient, KeychronM6HidClient, ModdoHidClient, ZaunkoenigHidClient, CorsairHidClient, FantechHidClient, WallhackMouseHidClient, WallhackKeyboardHidClient, GloriousHidClient, GloriousClassicHidClient, MchoseHidClient, MchoseDockHidClient, MicrosoftHidClient] as const;
const PULSAR_CLASSES = [PulsarHidClient, PulsarProHidClient, PulsarXs1HidClient] as const;

const logitechClient = (): LogitechHidppClient | null => activeAs(LogitechHidppClient);
Expand Down
2 changes: 2 additions & 0 deletions src/supported-mice.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -25,6 +25,7 @@ import { PULSAR_XS1_PRODUCT_IDS } from "@openmouse/protocol/pulsar";
import { RAZER_PRODUCTS } from "@openmouse/protocol/razer-devices";
import { TEEVOLUTION_PRODUCT_IDS } from "@openmouse/protocol/teevolution";
import { ZAUNKOENIG_PRODUCT_IDS } from "@openmouse/protocol/zaunkoenig";
import { CORSAIR_PRODUCT_IDS } from "@openmouse/protocol/corsair";

import { MICE, STATUS, type Mouse, type Status } from "./supported-mice.ts";

Expand DownExpand Up@@ -97,6 +98,7 @@ const PID_UNIVERSE = new Set<number>([
...KEYCHRON_NAPE_PRODUCTS.keys(),
...TEEVOLUTION_PRODUCT_IDS,
...ZAUNKOENIG_PRODUCT_IDS,
...CORSAIR_PRODUCT_IDS,
...NINJUTSO_LEGACY_MOUSE_PRODUCT_IDS,
...NINJUTSO_MOUSE_PRODUCT_IDS,
...NINJUTSO_LEGACY_RECEIVER_PRODUCT_IDS,
Expand Down
3 changes: 3 additions & 0 deletions src/supported-mice.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -346,6 +346,9 @@ export const MICE: Mouse[] = [
note: "DPI presets, polling, LED color, sleep/dim timers, default lighting, and buttons are write-only; battery percentage/charging is read live (no firmware-query command in this protocol). PID 0x184a (wired mode) and 0x1848 (2.4 GHz mode) in SteelSeries Prime Mini Wireless driver" },

// CORSAIR ─────────────────────────────────────────────────────────────
{ brand: "Corsair", model: "NIGHTSWORD RGB", status: "supported", req: 1,
pids: [0x1b5c],
note: "Read-only: identity, firmware, live DPI stages, polling rate, lift-off height, and angle snapping over the 0xffc2/usage-4 feature-report interface (fw 3.41). Close iCUE first — it holds the control interface. PID 0x1b5c in Corsair driver" },
{ brand: "Corsair", model: "Harpoon RGB Pro", status: "driver", req: 5,
note: "iCUE protocol — not implemented" },
{ brand: "Corsair", model: "Katar Pro", status: "driver", req: 4,
Expand Down
5 changes: 5 additions & 0 deletions src/ui/device-images.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -36,6 +36,11 @@ test("Razer Orochi V2 uses its own render over its Atheris receiver", () => {
assert.equal(deviceImage({ vendorId: 0x1532, productId: 0x0094 } as HIDDevice), CDN + "razer-orochi-v2.png");
});

test("Corsair NIGHTSWORD RGB falls back to the placeholder until art exists", () => {
assert.equal(deviceImage({ vendorId: 0x1b1c, productId: 0x1b5c } as HIDDevice, "Corsair NIGHTSWORD RGB"), CDN + "unknown-device.png");
assert.equal(deviceImage(null, "CORSAIR NIGHTSWORD RGB Gaming Mouse"), CDN + "unknown-device.png");
});

test("fixture previews resolve product art without a HID device", () => {
assert.equal(deviceImage(null, "CRDRAKO KO-ONE"), CDN + "crdrako-ko-one.png");
assert.equal(deviceImage(null, "Zaunkoenig M3K"), CDN + "zaunkoenig-m3k.png");
Expand Down
3 changes: 3 additions & 0 deletions src/ui/device-images.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -180,6 +180,9 @@ function resolveDeviceImageFilename(device: HIDDevice | null | undefined, displa
if (/\bterra\s*pro\b/i.test(displayName)) return "teevolution-terra-pro.png";
if (/\bm-001\b/i.test(displayName)) return "wallhack-m-001.png";
if (/\bk-001\b/i.test(displayName)) return "wallhack-k-001.png";
// Corsair NIGHTSWORD RGB has no product render yet; resolves to the generic
// placeholder until art is uploaded (then add ["1b1c:1b5c", ...] above).
if (/\bnightsword\b/i.test(displayName)) return "unknown-device.png";
// Newer supported-model artwork resolved from the reported product name. These
// run after the shared-receiver checks above but before the Pulsar/unknown
// catch-alls. Test-needed (likely) models are deliberately left out.
Expand Down
Loading