This commit is contained in:
parent
33b3448fb0
commit
290f433104
10
play.html
10
play.html
|
|
@ -231,6 +231,12 @@
|
||||||
background: #000;
|
background: #000;
|
||||||
box-shadow: 0 0 42px rgba(0, 0, 0, 0.95), 0 0 0 1px #2e251b;
|
box-shadow: 0 0 42px rgba(0, 0, 0, 0.95), 0 0 0 1px #2e251b;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
cursor: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#play-stage,
|
||||||
|
#play-stage * {
|
||||||
|
cursor: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#bnet-shell {
|
#bnet-shell {
|
||||||
|
|
@ -241,6 +247,7 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
background: #000;
|
background: #000;
|
||||||
|
cursor: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#bnet-canvas {
|
#bnet-canvas {
|
||||||
|
|
@ -251,6 +258,7 @@
|
||||||
aspect-ratio: 4 / 3;
|
aspect-ratio: 4 / 3;
|
||||||
display: block;
|
display: block;
|
||||||
image-rendering: pixelated;
|
image-rendering: pixelated;
|
||||||
|
cursor: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#view {
|
#view {
|
||||||
|
|
@ -262,6 +270,7 @@
|
||||||
background: #080706;
|
background: #080706;
|
||||||
z-index: 5;
|
z-index: 5;
|
||||||
image-rendering: pixelated;
|
image-rendering: pixelated;
|
||||||
|
cursor: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#d2-hud-canvas {
|
#d2-hud-canvas {
|
||||||
|
|
@ -273,6 +282,7 @@
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
image-rendering: pixelated;
|
image-rendering: pixelated;
|
||||||
|
cursor: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#play-disconnect-banner {
|
#play-disconnect-banner {
|
||||||
|
|
|
||||||
|
|
@ -321,6 +321,9 @@ export class FrontendRenderer {
|
||||||
|
|
||||||
constructor(canvas: HTMLCanvasElement, state: BnetFlowState) {
|
constructor(canvas: HTMLCanvasElement, state: BnetFlowState) {
|
||||||
this.canvas = canvas
|
this.canvas = canvas
|
||||||
|
if (this.canvas && this.canvas.style) {
|
||||||
|
this.canvas.style.cursor = 'none'
|
||||||
|
}
|
||||||
const ctx = canvas.getContext('2d')
|
const ctx = canvas.getContext('2d')
|
||||||
if (!ctx) throw new Error('Failed to acquire 2D context for bnet-canvas')
|
if (!ctx) throw new Error('Failed to acquire 2D context for bnet-canvas')
|
||||||
ctx.imageSmoothingEnabled = false
|
ctx.imageSmoothingEnabled = false
|
||||||
|
|
|
||||||
|
|
@ -148,6 +148,12 @@ export async function startPlayApp(options?: {
|
||||||
throw new Error('Missing required DOM elements in play.html')
|
throw new Error('Missing required DOM elements in play.html')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const el of [stageEl, bnetShell, bnetCanvas, viewCanvas, hudCanvas]) {
|
||||||
|
if (el.style) {
|
||||||
|
el.style.cursor = 'none'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const bootProgress = new BootProgressTracker({ stageEl }).install()
|
const bootProgress = new BootProgressTracker({ stageEl }).install()
|
||||||
|
|
||||||
const settingsStore = getGlobalSettingsStore()
|
const settingsStore = getGlobalSettingsStore()
|
||||||
|
|
@ -350,7 +356,7 @@ export async function startPlayApp(options?: {
|
||||||
chatInputEl.placeholder = 'Say...'
|
chatInputEl.placeholder = 'Say...'
|
||||||
chatInputEl.hidden = true
|
chatInputEl.hidden = true
|
||||||
chatInputEl.style.cssText =
|
chatInputEl.style.cssText =
|
||||||
'position:absolute;left:24px;bottom:64px;width:360px;max-width:calc(100% - 48px);box-sizing:border-box;z-index:25;background:rgba(10,8,6,0.92);border:1px solid #c8a858;color:#f2e6c8;padding:4px 8px;font:13px "D2Formal436",serif;outline:none;'
|
'position:absolute;left:24px;bottom:64px;width:360px;max-width:calc(100% - 48px);box-sizing:border-box;z-index:25;background:rgba(10,8,6,0.92);border:1px solid #c8a858;color:#f2e6c8;padding:4px 8px;font:13px "D2Formal436",serif;outline:none;cursor:none;'
|
||||||
stageEl.appendChild(chatInputEl)
|
stageEl.appendChild(chatInputEl)
|
||||||
|
|
||||||
const toggleInGameChatInput = (): void => {
|
const toggleInGameChatInput = (): void => {
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,8 @@ import {
|
||||||
} from '../src/common/items/cursor-meta.ts'
|
} from '../src/common/items/cursor-meta.ts'
|
||||||
import { BAKED_UI_MANIFEST } from '../src/common/items/baked-ui-meta.ts'
|
import { BAKED_UI_MANIFEST } from '../src/common/items/baked-ui-meta.ts'
|
||||||
import { HudManager, type HudCommandSink } from '../src/client/ui/hud-manager.ts'
|
import { HudManager, type HudCommandSink } from '../src/client/ui/hud-manager.ts'
|
||||||
|
import { FrontendRenderer } from '../src/client/frontend/frontend-renderer.ts'
|
||||||
|
import { createInitialFlowState } from '../src/client/frontend/flow-state.ts'
|
||||||
import { openGeneratedVendorShop } from './helpers/vendor-shop-fixture.ts'
|
import { openGeneratedVendorShop } from './helpers/vendor-shop-fixture.ts'
|
||||||
import { VENDOR_BUTTON_TABLE_X } from '../src/client/ui/world-panels.ts'
|
import { VENDOR_BUTTON_TABLE_X } from '../src/client/ui/world-panels.ts'
|
||||||
import { seedDemoHud } from './fixtures/hud-demo-state.ts'
|
import { seedDemoHud } from './fixtures/hud-demo-state.ts'
|
||||||
|
|
@ -522,6 +524,33 @@ describe('Diablo II v1.13c Dynamic Cursor System (Issue #148 & #491)', () => {
|
||||||
expect(hud.state.cursorTradeMode).toBeNull()
|
expect(hud.state.cursorTradeMode).toBeNull()
|
||||||
expect(hud.state.cursorAnimation).toBe('protate')
|
expect(hud.state.cursorAnimation).toBe('protate')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('hides the native OS triangle cursor across #play-stage, #view, #bnet-canvas, and #d2-hud-canvas per D2gfx.dll #10029 (0x6fa88290) (Issue #718)', () => {
|
||||||
|
// 1. FrontendRenderer hides native OS cursor on #bnet-canvas (D2Win.dll 0x6f8f7800 -> D2gfx.#10029)
|
||||||
|
const bnetCanvas = {
|
||||||
|
width: 800,
|
||||||
|
height: 600,
|
||||||
|
style: { cursor: 'default' },
|
||||||
|
getContext: () => ({ imageSmoothingEnabled: true }),
|
||||||
|
} as unknown as HTMLCanvasElement
|
||||||
|
const fe = new FrontendRenderer(bnetCanvas, createInitialFlowState())
|
||||||
|
expect(fe.canvas.style.cursor).toBe('none')
|
||||||
|
|
||||||
|
// 2. HudManager hides native OS cursor on #d2-hud-canvas (D2Client.dll 0x6fac63d0 -> D2gfx.#10029)
|
||||||
|
const { mockCanvas: hudCanvas } = createTestHud()
|
||||||
|
expect(hudCanvas.style.cursor).toBe('none')
|
||||||
|
|
||||||
|
// 3. play.html enforces cursor: none on #play-stage and all child canvases (#bnet-shell, #bnet-canvas, #view, #d2-hud-canvas)
|
||||||
|
// so pointer-events: none on #d2-hud-canvas over the game world never exposes the OS cursor on #view
|
||||||
|
const playHtml = readFileSync(join(process.cwd(), 'play.html'), 'utf8')
|
||||||
|
expect(playHtml).toMatch(/#play-stage\s*\{[^}]*cursor:\s*none;/s)
|
||||||
|
expect(playHtml).toMatch(/#play-stage,\s*#play-stage\s*\*\s*\{[^}]*cursor:\s*none\s*!important;/s)
|
||||||
|
expect(playHtml).toMatch(/#bnet-shell\s*\{[^}]*cursor:\s*none;/s)
|
||||||
|
expect(playHtml).toMatch(/#bnet-canvas\s*\{[^}]*cursor:\s*none;/s)
|
||||||
|
expect(playHtml).toMatch(/#view\s*\{[^}]*cursor:\s*none;/s)
|
||||||
|
expect(playHtml).toMatch(/#d2-hud-canvas\s*\{[^}]*cursor:\s*none;/s)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue