diff --git a/src/check-scan.ts b/src/check-scan.ts index 65c4691..a774a0c 100644 --- a/src/check-scan.ts +++ b/src/check-scan.ts @@ -31,6 +31,8 @@ export const BRANDS: Record = { 0x0C45: "Redragon", 0x1BCF: "Alienware", 0x3151: "Fantech", + 0xA8A4: "K-snake", + 0xA8A5: "K-snake", }; const OPENMOUSE_SUPPORTED = new Set([ diff --git a/src/supported-mice.ts b/src/supported-mice.ts index 5ac20ee..96974a0 100644 --- a/src/supported-mice.ts +++ b/src/supported-mice.ts @@ -552,6 +552,8 @@ export const MICE: Mouse[] = [ note: "CM protocol — not implemented" }, { brand: "Cooler Master", model: "MM711", status: "driver", req: 1, note: "CM protocol — not implemented" }, + { brand: "K-snake", model: "X11", status: "driver", req: 1, + note: "VID 0xA8A4 (USB) / 0xA8A5 (2.4G) PID 0x2255 — 0x55-framed output-report protocol, vendor panel reverse-engineered, driver in progress in mouse-protocol" }, // UNKNOWNS ──────────────────────────────────────────────────────────── { brand: "Hitscan", model: "Hyperlight", status: "unknown", req: 5, diff --git a/src/ui/device-images.test.ts b/src/ui/device-images.test.ts index 4ce8535..f2b4a59 100644 --- a/src/ui/device-images.test.ts +++ b/src/ui/device-images.test.ts @@ -200,3 +200,11 @@ test("test-needed and unsupported models are not given new artwork", () => { assert.equal(deviceImage(null, "VGN Dragonfly R1 Pro"), CDN + "unknown-device.png"); assert.equal(deviceImage(null, "Razer Viper 8KHz"), CDN + "unknown-device.png"); }); + +test("K-snake X11 wired and dongle share the same artwork", () => { + const wired = { vendorId: 0xa8a4, productId: 0x2255 } as HIDDevice; + const dongle = { vendorId: 0xa8a5, productId: 0x2255 } as HIDDevice; + assert.equal(deviceImage(wired), CDN + "ksnake-x11.png"); + assert.equal(deviceImage(dongle), CDN + "ksnake-x11.png"); + assert.equal(deviceImage(null, "K-snake X11"), CDN + "ksnake-x11.png"); +}); diff --git a/src/ui/device-images.ts b/src/ui/device-images.ts index dd73e71..a7e7139 100644 --- a/src/ui/device-images.ts +++ b/src/ui/device-images.ts @@ -135,6 +135,9 @@ const DEVICE_IMAGES: ReadonlyMap = new Map([ ["1532:00b8", "razer-viper-v3-hyperspeed.png"], ["1532:00e5", "razer-viper-v4-pro.png"], ["1532:00e6", "razer-viper-v4-pro.png"], + // K-snake X11 wired / 2.4 GHz dongle share the same shell. + ["a8a4:2255", "ksnake-x11.png"], + ["a8a5:2255", "ksnake-x11.png"], ]); function deviceKey(device: HIDDevice): string { @@ -195,6 +198,8 @@ function resolveDeviceImageFilename(device: HIDDevice | null | undefined, displa if (/\bsword\s*x\b/i.test(displayName)) return "wlmouse-sword-x.png"; if (/\bdragonfly\s*f2\b/i.test(displayName)) return "vgn-dragonfly-f2.png"; if (/\bmaya\s*x\b/i.test(displayName)) return "lamzu-maya-x.png"; + if (/\bk-snake\b/i.test(displayName)) return "ksnake-x11.png"; + if (/\bx11\b/i.test(displayName)) return "ksnake-x11.png"; if (/\bf1\s*v2\b/i.test(displayName)) return "atk-f1-v2-ultra-max.png"; // Catches any A7 V2 variant whose product id is not pinned above. if (/\ba7\s*v2\b/i.test(displayName)) return "mchose-a7-v2.png";