@jshookmcp/jshook 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -50
- package/README.zh.md +25 -48
- package/dist/AntiCheatDetector-CGVGNfy5.mjs +1 -0
- package/dist/CacheAdapters-CdAxBmVW.mjs +1 -0
- package/dist/CodeInjector-BlgyqTOk.mjs +1 -0
- package/dist/ConsoleMonitor-Dkqc0HNi.mjs +490 -0
- package/dist/DOMInspector-BYY_EJ0C.mjs +95 -0
- package/dist/DarwinAPI-DC4HGGLl.mjs +1 -0
- package/dist/DetailedDataManager-BniBJlVv.mjs +1 -0
- package/dist/EventBus-DgciURGg.mjs +1 -0
- package/dist/EvidenceGraphBridge-BIfgB7HP.mjs +1 -0
- package/dist/ExtensionManager-erMpqcLk.mjs +1 -0
- package/dist/FingerprintManager-N7BZqjxP.mjs +1 -0
- package/dist/HardwareBreakpoint-OcJqNFVc.mjs +1 -0
- package/dist/HeapAnalyzer-CqAxZzeS.mjs +1 -0
- package/dist/{HookGeneratorBuilders.core.generators.storage-CTbB4Lcx.mjs → HookGeneratorBuilders.core.generators.storage-Bf1fbrNK.mjs} +66 -101
- package/dist/InstrumentationSession-DxXs0sCp.mjs +1 -0
- package/dist/MCPServer.search.handlers.domain-DVbWL1bT.mjs +1 -0
- package/dist/MemoryController-BaqstM5w.mjs +2 -0
- package/dist/MemoryScanSession-CaxAjZJf.mjs +1 -0
- package/dist/MemoryScanner-BLYnMJy6.mjs +1 -0
- package/dist/NativeMemoryManager.impl-CI554XbY.mjs +1 -0
- package/dist/NativeMemoryManager.utils-DM4NC3FE.mjs +1 -0
- package/dist/PEAnalyzer-DJyaJTQJ.mjs +1 -0
- package/dist/PageController-D9jVkH0i.mjs +1 -0
- package/dist/PointerChainEngine-5nF9eNlu.mjs +1 -0
- package/dist/PrerequisiteError-Bl3dK8XA.mjs +1 -0
- package/dist/ProcessRegistry-Hf12LlR9.mjs +1 -0
- package/dist/ResponseBuilder-B2lu4KEl.mjs +1 -0
- package/dist/ReverseEvidenceGraph-B931HeoW.mjs +2 -0
- package/dist/ScriptManager-fgqiALgj.mjs +7 -0
- package/dist/Speedhack-l6s8L2Qw.mjs +1 -0
- package/dist/StealthVerifier-Dhbj4B4P.mjs +1 -0
- package/dist/StructureAnalyzer-A-WamfYE.mjs +2 -0
- package/dist/ToolCatalog-D_IKl1Hu.mjs +1 -0
- package/dist/ToolError-DWU_z7gp.mjs +1 -0
- package/dist/ToolProbe-xsfALmN3.mjs +1 -0
- package/dist/ToolRegistry-B0Zs-phN.mjs +1 -0
- package/dist/ToolRouter.policy-CFHoN_Lw.mjs +4 -0
- package/dist/TraceRecorder-Dd8jLXpi.mjs +272 -0
- package/dist/VersionDetector-DMoUWyNm.mjs +9 -0
- package/dist/Win32API-Bhi5xFBe.mjs +1 -0
- package/dist/Win32Debug-CQteFL4F.mjs +1 -0
- package/dist/WorkflowEngine-CxEp2WXH.mjs +1 -0
- package/dist/analysis-BuR-NgX8.mjs +5 -0
- package/dist/{antidebug-BRKeyt27.mjs → antidebug-BOTZH6-0.mjs} +8 -259
- package/dist/artifactRetention-NBdncOEW.mjs +1 -0
- package/dist/artifacts-B5xQuEa_.mjs +1 -0
- package/dist/authorization-schema-B40obG1A.mjs +1 -0
- package/dist/betterSqlite3-CGaxz4AX.mjs +1 -0
- package/dist/binary-instrument-Cf9qqLlM.mjs +7 -0
- package/dist/bind-helpers-BlAOQrFQ.mjs +1 -0
- package/dist/boringssl-inspector-BST5vtKx.mjs +2 -0
- package/dist/browser-C4Le3xqA.mjs +11 -0
- package/dist/capabilities-DbYCv-HF.mjs +1 -0
- package/dist/chunk-C_pMuVsO.mjs +1 -0
- package/dist/collector-CKO8RPK8.mjs +1 -0
- package/dist/concurrency-CcK46d0h.mjs +1 -0
- package/dist/constants-Cp6hBrrx.mjs +1 -0
- package/dist/coordination-BbijHEHH.mjs +1 -0
- package/dist/debugger-CRJq_krh.mjs +1 -0
- package/dist/definitions-BGobEDQa.mjs +1 -0
- package/dist/definitions-BGwNSkVm.mjs +1 -0
- package/dist/definitions-BbxOUiP-.mjs +1 -0
- package/dist/definitions-CCP9gphV.mjs +1 -0
- package/dist/definitions-CIO9O-Sw.mjs +1 -0
- package/dist/definitions-CYFbewnd.mjs +1 -0
- package/dist/definitions-CdWEuIkI.mjs +1 -0
- package/dist/definitions-CoQFbggH.mjs +1 -0
- package/dist/definitions-CuJRsJ6N.mjs +1 -0
- package/dist/definitions-DI9YXsJk.mjs +1 -0
- package/dist/definitions-DJklW2sS.mjs +1 -0
- package/dist/definitions-DZ8uKusP.mjs +1 -0
- package/dist/definitions-Dds_zrWx.mjs +1 -0
- package/dist/definitions-Dgrg7f3D.mjs +1 -0
- package/dist/definitions-DtE0XLrT.mjs +1 -0
- package/dist/definitions-LaYTuwQd.mjs +26 -0
- package/dist/definitions-NoVp_9Pm.mjs +1 -0
- package/dist/definitions-OvGsfxdt.mjs +1 -0
- package/dist/definitions-jXPaVy4P.mjs +1 -0
- package/dist/encoding-DGcr6Aj_.mjs +2 -0
- package/dist/ensure-browser-core-Buls24LQ.mjs +1 -0
- package/dist/evidence-graph-bridge-B0yhGPcs.mjs +1 -0
- package/dist/factory-Cx_1LorX.mjs +1 -0
- package/dist/flat-target-session-CO5g78k3.mjs +1 -0
- package/dist/formatAddress-C7j2fDlM.mjs +1 -0
- package/dist/graphql-HLf3MS8H.mjs +62 -0
- package/dist/handlers-BLMa4X7l.mjs +54 -0
- package/dist/handlers-BP12ZsWc.mjs +4 -0
- package/dist/handlers-BZoPla6E.mjs +1 -0
- package/dist/handlers-BggKiVx9.mjs +2 -0
- package/dist/handlers-D3iev8g1.mjs +1 -0
- package/dist/handlers-D49r1-1P.mjs +1 -0
- package/dist/handlers-DCE45Ww8.mjs +2 -0
- package/dist/handlers-DW5AbYs5.mjs +5 -0
- package/dist/handlers-De5u62Ga2.mjs +1 -0
- package/dist/handlers-DmQzIc44.mjs +31 -0
- package/dist/handlers-DnJRGp7t.mjs +302 -0
- package/dist/handlers-Dv_runVv.mjs +2 -0
- package/dist/handlers-S9Ws0IGy.mjs +2 -0
- package/dist/{handlers-Dz9PYsCa.mjs → handlers-pVNpaw4A.mjs} +118 -904
- package/dist/handlers.impl-CD2_kOcC.mjs +1 -0
- package/dist/hooks-DDKppogd.mjs +600 -0
- package/dist/index.mjs +12 -5235
- package/dist/logger-sBC6IdRT.mjs +1 -0
- package/dist/maintenance-CutEO84j.mjs +1 -0
- package/dist/manifest-BFGxlDRh.mjs +123 -0
- package/dist/manifest-BPuE6oH2.mjs +1 -0
- package/dist/manifest-BXry5N09.mjs +1 -0
- package/dist/manifest-BeP_zJGb2.mjs +1 -0
- package/dist/manifest-C0g67k6U.mjs +1 -0
- package/dist/manifest-C1nZkTkO.mjs +1 -0
- package/dist/manifest-C7qV1z7F.mjs +1 -0
- package/dist/manifest-CDeUZGUZ.mjs +1 -0
- package/dist/manifest-CDiCtaQT.mjs +1 -0
- package/dist/manifest-CFn0359q2.mjs +1 -0
- package/dist/manifest-CGq4NpqH2.mjs +1 -0
- package/dist/manifest-CJMGt7Qy.mjs +1 -0
- package/dist/manifest-CRIJq4Hs.mjs +1 -0
- package/dist/manifest-C_hEIjSx.mjs +1 -0
- package/dist/manifest-CeQmtQOY.mjs +1 -0
- package/dist/manifest-Cq0j7GZt.mjs +1 -0
- package/dist/manifest-CtPmHAdn.mjs +1 -0
- package/dist/manifest-Cx2IVMUY.mjs +1 -0
- package/dist/manifest-D16xPXro.mjs +1 -0
- package/dist/manifest-D44TaRJU.mjs +1 -0
- package/dist/manifest-D610kxZr.mjs +2 -0
- package/dist/manifest-DC-SMF6b.mjs +1 -0
- package/dist/manifest-DD3rtxvV.mjs +1 -0
- package/dist/manifest-DKUorv5M.mjs +1 -0
- package/dist/manifest-DMJlcsTR.mjs +1 -0
- package/dist/manifest-DWUUWBz0.mjs +1 -0
- package/dist/manifest-De-6Wf2R.mjs +1 -0
- package/dist/manifest-Dgh0uDW-.mjs +1 -0
- package/dist/manifest-Dm0o3i2U.mjs +1 -0
- package/dist/manifest-DsVh7Y4U.mjs +1 -0
- package/dist/manifest-DtEFSRaq.mjs +1 -0
- package/dist/manifest-H-EpAyZQ.mjs +1 -0
- package/dist/manifest-ais9Afrw.mjs +1 -0
- package/dist/manifest-tmb54wmA.mjs +1 -0
- package/dist/manifest-yu2xiQqe.mjs +1 -0
- package/dist/manifest-zrbrpKCC.mjs +1 -0
- package/dist/matchesWildcardPattern-BGqLSmEs.mjs +1 -0
- package/dist/modules-p-PUNv9r.mjs +332 -0
- package/dist/mojo-ipc-VGlv3Qyp.mjs +9 -0
- package/dist/network-BjZ1Y-GB.mjs +7 -0
- package/dist/outputPaths-BonGThuc.mjs +2 -0
- package/dist/parse-args-Cuk7-xUt.mjs +1 -0
- package/dist/platform-C446Lf97.mjs +93 -0
- package/dist/playwright-cdp-fallback-BwVR-_T3.mjs +1 -0
- package/dist/process-C9f2A5zk.mjs +962 -0
- package/dist/proxy-CvRepxgV.mjs +1 -0
- package/dist/registry-DUHIPE-v.mjs +1 -0
- package/dist/response-C7rKQst4.mjs +1 -0
- package/dist/search-defaults-D2bY-rzH.mjs +1 -0
- package/dist/server/plugin-api.mjs +1 -293
- package/dist/shared-state-board-Cyg-xh_k.mjs +1 -0
- package/dist/sourcemap-D6Q1UuAp.mjs +1 -0
- package/dist/ssrf-policy-T96MR3r6.mjs +1 -0
- package/dist/streaming-CTX58tbb.mjs +1 -0
- package/dist/tool-builder-CI9914Tf.mjs +1 -0
- package/dist/transform-Cv9P2vVD.mjs +103 -0
- package/dist/types-CuyefmGT.mjs +1 -0
- package/dist/types-DtThH00r.mjs +1 -0
- package/dist/wasm-DaJa8J0V.mjs +174 -0
- package/dist/webcrack-CsLLJIs9.mjs +46 -0
- package/dist/workflow-CYIXtrWD.mjs +101 -0
- package/package.json +50 -78
- package/dist/AntiCheatDetector-CqGDXmfc.mjs +0 -350
- package/dist/CacheAdapters-jJFy20G-.mjs +0 -80
- package/dist/CodeInjector-BdjRfNx7.mjs +0 -150
- package/dist/ConsoleMonitor-DykL3IAw.mjs +0 -2269
- package/dist/DarwinAPI-ETyy0xyo.mjs +0 -363
- package/dist/DetailedDataManager-HT49OrvF.mjs +0 -217
- package/dist/EventBus-DFKvADm3.mjs +0 -141
- package/dist/EvidenceGraphBridge-318Oi0Lf.mjs +0 -153
- package/dist/ExtensionManager-BDMsY2Dz.mjs +0 -721
- package/dist/FingerprintManager-BN4UQWnX.mjs +0 -96
- package/dist/HardwareBreakpoint-Cc2AFq1Y.mjs +0 -239
- package/dist/HeapAnalyzer-DruMgsgj.mjs +0 -284
- package/dist/InstrumentationSession-DLH0vd-z.mjs +0 -244
- package/dist/MemoryController-CMtviNW_.mjs +0 -167
- package/dist/MemoryScanSession-ITgb_NMi.mjs +0 -278
- package/dist/MemoryScanner-CiL7Z3ey.mjs +0 -428
- package/dist/NativeMemoryManager.impl-D9Lkovvn.mjs +0 -485
- package/dist/NativeMemoryManager.utils-BBlAixF5.mjs +0 -165
- package/dist/PEAnalyzer-DMQ44gen.mjs +0 -385
- package/dist/PageController-BPJNqqBN.mjs +0 -431
- package/dist/PointerChainEngine-K7wN8Z-w.mjs +0 -325
- package/dist/PrerequisiteError-TuyZIs6n.mjs +0 -20
- package/dist/ProcessRegistry-zGg12QbE.mjs +0 -74
- package/dist/ResponseBuilder-CJXWmWNw.mjs +0 -143
- package/dist/ReverseEvidenceGraph-C02-gXOh.mjs +0 -269
- package/dist/ScriptManager-ZuWD-0Jg.mjs +0 -3003
- package/dist/Speedhack-D-z0umeT.mjs +0 -156
- package/dist/StealthVerifier-BWmPgQsv.mjs +0 -135
- package/dist/StructureAnalyzer-Cav5AVSL.mjs +0 -429
- package/dist/ToolCatalog-5OJdMiF0.mjs +0 -582
- package/dist/ToolError-jh9whhMd.mjs +0 -15
- package/dist/ToolProbe-DbCFGyrg.mjs +0 -45
- package/dist/ToolRegistry-B9krbTtI.mjs +0 -180
- package/dist/ToolRouter.policy-BGDAGyeH.mjs +0 -344
- package/dist/TraceRecorder-B41Z5XBj.mjs +0 -1286
- package/dist/VersionDetector-K3V4vGsw.mjs +0 -104
- package/dist/Win32API-C2kjj0ze.mjs +0 -346
- package/dist/Win32Debug-CKrGOTpo.mjs +0 -274
- package/dist/WorkflowEngine-DJ6M4opp.mjs +0 -569
- package/dist/analysis-BHeJW2Nb.mjs +0 -1234
- package/dist/artifactRetention-CPXkUJXp.mjs +0 -598
- package/dist/artifacts-DkfosXH3.mjs +0 -59
- package/dist/authorization-schema-DRqyJMSk.mjs +0 -31
- package/dist/betterSqlite3-DLSBZodi.mjs +0 -74
- package/dist/binary-instrument--V3MAhJ4.mjs +0 -971
- package/dist/bind-helpers-ClV34xdn.mjs +0 -42
- package/dist/boringssl-inspector-Bo_LOLaS.mjs +0 -180
- package/dist/browser-Dx3_S2cG.mjs +0 -4369
- package/dist/capabilities-CcHlvWgK.mjs +0 -33
- package/dist/chunk-CjcI7cDX.mjs +0 -15
- package/dist/concurrency-Drev_Vz9.mjs +0 -41
- package/dist/constants-CDZLOoVv.mjs +0 -534
- package/dist/coordination-DgItD9DL.mjs +0 -259
- package/dist/debugger-RS3RSAqs.mjs +0 -1288
- package/dist/definitions-BEoYofW5.mjs +0 -47
- package/dist/definitions-BRaefg3u.mjs +0 -365
- package/dist/definitions-BbkvZkiv.mjs +0 -96
- package/dist/definitions-BtWSHJ3o.mjs +0 -17
- package/dist/definitions-C1gCHO0i.mjs +0 -43
- package/dist/definitions-CDOg_b-l.mjs +0 -138
- package/dist/definitions-CVPD9hzZ.mjs +0 -54
- package/dist/definitions-Cea8Lgl7.mjs +0 -94
- package/dist/definitions-DAgIyjxM.mjs +0 -10
- package/dist/definitions-DJA27nsL.mjs +0 -66
- package/dist/definitions-DKPFU3LW.mjs +0 -25
- package/dist/definitions-DPRpZQ96.mjs +0 -47
- package/dist/definitions-DUE5gmdn.mjs +0 -18
- package/dist/definitions-DYVjOtxa.mjs +0 -26
- package/dist/definitions-DcYLVLCo.mjs +0 -37
- package/dist/definitions-Pp5LI2H4.mjs +0 -27
- package/dist/definitions-j9KdHVNR.mjs +0 -14
- package/dist/definitions-uzkjBwa7.mjs +0 -258
- package/dist/definitions-va-AnLuQ.mjs +0 -28
- package/dist/encoding-DJeqHmpd.mjs +0 -1079
- package/dist/evidence-graph-bridge-DcYizFk2.mjs +0 -136
- package/dist/factory-C90tBff6.mjs +0 -575
- package/dist/flat-target-session-Dgax2Cy3.mjs +0 -29
- package/dist/formatAddress-nnMvEohD.mjs +0 -17
- package/dist/graphql-CoHrhweh.mjs +0 -1197
- package/dist/handlers-4jmR0nMs.mjs +0 -898
- package/dist/handlers-BAHPxcch.mjs +0 -789
- package/dist/handlers-BOs9b907.mjs +0 -2600
- package/dist/handlers-BWXEy6ef.mjs +0 -917
- package/dist/handlers-Bndn6QvE.mjs +0 -111
- package/dist/handlers-BqC4bD4s.mjs +0 -681
- package/dist/handlers-BtYq60bM2.mjs +0 -276
- package/dist/handlers-BzgcB4iv.mjs +0 -799
- package/dist/handlers-CRyRWj2b.mjs +0 -859
- package/dist/handlers-CVv2H1uq.mjs +0 -592
- package/dist/handlers-Dl5a7JS4.mjs +0 -572
- package/dist/handlers-Dx2d7jt7.mjs +0 -2537
- package/dist/handlers-HujRKC3b.mjs +0 -661
- package/dist/handlers.impl-XWXkQfyi.mjs +0 -807
- package/dist/hooks-B1B8NRHL.mjs +0 -898
- package/dist/logger-Dh_xb7_2.mjs +0 -93
- package/dist/maintenance-PRMkLVRW.mjs +0 -835
- package/dist/manifest-67Bok-Si.mjs +0 -58
- package/dist/manifest-6lNTMZAB2.mjs +0 -87
- package/dist/manifest-B2duEHiH.mjs +0 -90
- package/dist/manifest-B6EY9Vm8.mjs +0 -57
- package/dist/manifest-B6nKSbyY.mjs +0 -95
- package/dist/manifest-BL8AQNPF.mjs +0 -106
- package/dist/manifest-BSZvJJmV.mjs +0 -47
- package/dist/manifest-BU7qzUyX.mjs +0 -418
- package/dist/manifest-Bl62e8WK.mjs +0 -49
- package/dist/manifest-Bo5cXjdt.mjs +0 -82
- package/dist/manifest-BpS4gtUK.mjs +0 -1347
- package/dist/manifest-Bv65_e2W.mjs +0 -101
- package/dist/manifest-BytNIF4Z.mjs +0 -117
- package/dist/manifest-C-xtsjS3.mjs +0 -81
- package/dist/manifest-CDYl7OhA.mjs +0 -66
- package/dist/manifest-CRZ3xmkD.mjs +0 -61
- package/dist/manifest-CoW6u4Tp.mjs +0 -132
- package/dist/manifest-Cq5zN_8A.mjs +0 -50
- package/dist/manifest-D7YZM_2e.mjs +0 -194
- package/dist/manifest-DE_VrAeQ.mjs +0 -314
- package/dist/manifest-DGsXSCpT.mjs +0 -39
- package/dist/manifest-DJ2vfEuW.mjs +0 -156
- package/dist/manifest-DPXDYhEu.mjs +0 -80
- package/dist/manifest-Dd4fQb0a.mjs +0 -322
- package/dist/manifest-Deq6opGg.mjs +0 -223
- package/dist/manifest-DfJTafJK.mjs +0 -37
- package/dist/manifest-DgOdgN_j.mjs +0 -50
- package/dist/manifest-DlbMW4v4.mjs +0 -47
- package/dist/manifest-DmVfbH0w.mjs +0 -374
- package/dist/manifest-Dog6Ddjr.mjs +0 -109
- package/dist/manifest-DvgU5FWb.mjs +0 -58
- package/dist/manifest-HsfDBs7j.mjs +0 -50
- package/dist/manifest-I8oQHvCG.mjs +0 -186
- package/dist/manifest-NvH_a-av.mjs +0 -786
- package/dist/manifest-cEJU1v0Z.mjs +0 -129
- package/dist/manifest-wOl5XLB12.mjs +0 -112
- package/dist/modules-tZozf0LQ.mjs +0 -10635
- package/dist/mojo-ipc-DXNEXEqb.mjs +0 -640
- package/dist/network-CPVvwvFg.mjs +0 -3852
- package/dist/outputPaths-um7lCRY3.mjs +0 -1141
- package/dist/parse-args-B4cY5Vx5.mjs +0 -39
- package/dist/platform-CYeFoTWp.mjs +0 -2161
- package/dist/process-BTbgcVc6.mjs +0 -1306
- package/dist/proxy-r8YN6nP1.mjs +0 -192
- package/dist/registry-Bl8ZQW61.mjs +0 -34
- package/dist/response-CWhh2aLo.mjs +0 -34
- package/dist/shared-state-board-BoZnSoj-.mjs +0 -586
- package/dist/sourcemap-BIDHUVXy.mjs +0 -934
- package/dist/ssrf-policy-Dsqd-DTX.mjs +0 -166
- package/dist/streaming-Dal6utPp.mjs +0 -725
- package/dist/tool-builder-BHJp32mV.mjs +0 -186
- package/dist/transform-DRVgGG90.mjs +0 -1011
- package/dist/types-Bx92KJfT.mjs +0 -4
- package/dist/types-DDBWs9UP.mjs +0 -37
- package/dist/wasm-BYx5UOeG.mjs +0 -1044
- package/dist/webcrack-Be0_FccV.mjs +0 -747
- package/dist/workflow-BpuKEtvn.mjs +0 -725
|
@@ -1,19 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { r as argNumber } from "./parse-args-B4cY5Vx5.mjs";
|
|
3
|
-
//#region src/server/domains/canvas/adapters/cocos-adapter.ts
|
|
4
|
-
/**
|
|
5
|
-
* Generates a self-contained JS string that traverses the Cocos Creator scene graph
|
|
6
|
-
* via cc.director.getScene() using DFS and returns a serialisable scene tree.
|
|
7
|
-
*
|
|
8
|
-
* Supports both v2 (cc.Node._children) and v3 (cc.Node.children) APIs.
|
|
9
|
-
* World bounds are computed from worldPosition + contentSize (v3) or getBoundingBox() (v2).
|
|
10
|
-
*
|
|
11
|
-
* @param opts - Dump options (maxDepth, onlyInteractive, onlyVisible)
|
|
12
|
-
*/
|
|
13
|
-
function buildCocosSceneTreeDumpPayload(opts) {
|
|
14
|
-
const maxDepth = opts.maxDepth ?? 20;
|
|
15
|
-
const onlyInteractive = opts.onlyInteractive ?? false;
|
|
16
|
-
return `(function() {
|
|
1
|
+
import{n as e}from"./response-C7rKQst4.mjs";import{r as t}from"./parse-args-Cuk7-xUt.mjs";function n(e){let t=e.maxDepth??20,n=e.onlyInteractive??!1;return`(function() {
|
|
17
2
|
function getChildren(node) {
|
|
18
3
|
if (!node) return [];
|
|
19
4
|
// v3 uses node.children, v2 uses node._children
|
|
@@ -85,8 +70,22 @@ function buildCocosSceneTreeDumpPayload(opts) {
|
|
|
85
70
|
var py = safeProp(node, 'y', 0) || 0;
|
|
86
71
|
var sx2 = safeProp(node, 'scaleX', 1);
|
|
87
72
|
var sy2 = safeProp(node, 'scaleY', 1);
|
|
88
|
-
var w2 = safeProp(
|
|
89
|
-
|
|
73
|
+
var w2 = safeProp(
|
|
74
|
+
node,
|
|
75
|
+
'_contentSize') && safeProp(node._contentSize,
|
|
76
|
+
'width',
|
|
77
|
+
0) || safeProp(node,
|
|
78
|
+
'width',
|
|
79
|
+
0,
|
|
80
|
+
);
|
|
81
|
+
var h2 = safeProp(
|
|
82
|
+
node,
|
|
83
|
+
'_contentSize') && safeProp(node._contentSize,
|
|
84
|
+
'height',
|
|
85
|
+
0) || safeProp(node,
|
|
86
|
+
'height',
|
|
87
|
+
0,
|
|
88
|
+
);
|
|
90
89
|
return {
|
|
91
90
|
x: px, y: py,
|
|
92
91
|
width: Math.abs(w2 * sx2),
|
|
@@ -111,7 +110,8 @@ function buildCocosSceneTreeDumpPayload(opts) {
|
|
|
111
110
|
if (comps && Array.isArray(comps)) {
|
|
112
111
|
for (var ci = 0; ci < comps.length; ci++) {
|
|
113
112
|
var c = comps[ci];
|
|
114
|
-
if (c && c.constructor && (c.constructor.name === 'Button' || c.constructor.name === 'UICanvas' || c.constructor.name === 'Sprite'))
|
|
113
|
+
if (c && c.constructor && (c.constructor.name === 'Button' || c.constructor.name === 'UICanvas' || c.constructor.name === 'Sprite'))
|
|
114
|
+
{
|
|
115
115
|
return true;
|
|
116
116
|
}
|
|
117
117
|
}
|
|
@@ -186,15 +186,15 @@ function buildCocosSceneTreeDumpPayload(opts) {
|
|
|
186
186
|
var totalNodes = 0;
|
|
187
187
|
|
|
188
188
|
function traverse(node, depth, path) {
|
|
189
|
-
if (!node || depth > ${
|
|
189
|
+
if (!node || depth > ${t}) return null;
|
|
190
190
|
totalNodes++;
|
|
191
191
|
|
|
192
192
|
var active = getActive(node);
|
|
193
193
|
var interactive = isInteractive(node);
|
|
194
194
|
var visible = active;
|
|
195
195
|
|
|
196
|
-
if (${
|
|
197
|
-
if (${
|
|
196
|
+
if (${e.onlyVisible??!1} && !visible) return null;
|
|
197
|
+
if (${n} && !interactive) return null;
|
|
198
198
|
|
|
199
199
|
var wb = getWorldBounds(node);
|
|
200
200
|
var pos = getPosition(node);
|
|
@@ -294,22 +294,7 @@ function buildCocosSceneTreeDumpPayload(opts) {
|
|
|
294
294
|
completeness: sceneTree ? 'full' : 'partial',
|
|
295
295
|
_meta: { isV3: isV3 }
|
|
296
296
|
};
|
|
297
|
-
})()
|
|
298
|
-
}
|
|
299
|
-
/**
|
|
300
|
-
* Generates a self-contained JS string that:
|
|
301
|
-
* 1. Transforms screen coordinates → canvas coordinates
|
|
302
|
-
* 2. Flips Y axis (Cocos uses bottom-left origin, browser uses top-left)
|
|
303
|
-
* 3. Runs hit test via engine (v3) or recursive DFS bounds check (v2 / fallback)
|
|
304
|
-
* 4. Returns all candidates sorted by depth (topmost first)
|
|
305
|
-
*
|
|
306
|
-
* @param opts - Pick options (x, y, canvasId)
|
|
307
|
-
*/
|
|
308
|
-
function buildCocosHitTestPayload(opts) {
|
|
309
|
-
const x = opts.x;
|
|
310
|
-
const y = opts.y;
|
|
311
|
-
const canvasId = opts.canvasId;
|
|
312
|
-
return `(function() {
|
|
297
|
+
})()`}function r(e){let t=e.x,n=e.y,r=e.canvasId;return`(function() {
|
|
313
298
|
function getChildren(node) {
|
|
314
299
|
if (!node) return [];
|
|
315
300
|
if (node.children && Array.isArray(node.children)) return node.children;
|
|
@@ -374,7 +359,9 @@ function buildCocosHitTestPayload(opts) {
|
|
|
374
359
|
var sx2 = safeProp(node, 'scaleX', 1);
|
|
375
360
|
var sy2 = safeProp(node, 'scaleY', 1);
|
|
376
361
|
var w2 = safeProp(node, '_contentSize') ? safeProp(node._contentSize, 'width', 0) : safeProp(node, 'width', 0);
|
|
377
|
-
var h2 = safeProp(node, '_contentSize') ?
|
|
362
|
+
var h2 = safeProp(node, '_contentSize') ?
|
|
363
|
+
safeProp(node._contentSize, 'height', 0) :
|
|
364
|
+
safeProp(node, 'height', 0);
|
|
378
365
|
return {
|
|
379
366
|
x: px, y: py,
|
|
380
367
|
width: Math.abs(w2 * sx2),
|
|
@@ -453,12 +440,12 @@ function buildCocosHitTestPayload(opts) {
|
|
|
453
440
|
return parts.join('/');
|
|
454
441
|
}
|
|
455
442
|
|
|
456
|
-
var sx = ${
|
|
443
|
+
var sx = ${t}, sy = ${n};
|
|
457
444
|
|
|
458
445
|
// Find the target canvas
|
|
459
446
|
var canvases = Array.from(document.querySelectorAll('canvas'));
|
|
460
447
|
var targetCanvas = null;
|
|
461
|
-
${
|
|
448
|
+
${r?`targetCanvas = document.getElementById(${JSON.stringify(r)}) || canvases[parseInt(${JSON.stringify(r)})] || null;`:`
|
|
462
449
|
for (var ci = canvases.length - 1; ci >= 0; ci--) {
|
|
463
450
|
var r = canvases[ci].getBoundingClientRect();
|
|
464
451
|
if (sx >= r.left && sx <= r.right && sy >= r.top && sy <= r.bottom) {
|
|
@@ -594,24 +581,7 @@ function buildCocosHitTestPayload(opts) {
|
|
|
594
581
|
},
|
|
595
582
|
hitTestMethod: finalMethod
|
|
596
583
|
};
|
|
597
|
-
})()`;
|
|
598
|
-
}
|
|
599
|
-
/**
|
|
600
|
-
* Cocos Creator canvas engine adapter.
|
|
601
|
-
*
|
|
602
|
-
* Handles both Cocos Creator 2.x and 3.x. Version is resolved from cc.ENGINE_VERSION
|
|
603
|
-
* at detect() time.
|
|
604
|
-
*/
|
|
605
|
-
var CocosCanvasAdapter = class {
|
|
606
|
-
id = "cocos";
|
|
607
|
-
engine = "CocosCreator";
|
|
608
|
-
version;
|
|
609
|
-
constructor() {
|
|
610
|
-
this.version = void 0;
|
|
611
|
-
}
|
|
612
|
-
async detect(env) {
|
|
613
|
-
try {
|
|
614
|
-
const result = await env.pageController.evaluate(`
|
|
584
|
+
})()`}var i=class{id=`cocos`;engine=`CocosCreator`;version;constructor(){this.version=void 0}async detect(e){try{let t=await e.pageController.evaluate(`
|
|
615
585
|
(function() {
|
|
616
586
|
if (typeof window.cc === 'undefined' || window.cc === null) {
|
|
617
587
|
return { present: false, hasDirector: false };
|
|
@@ -628,75 +598,7 @@ var CocosCanvasAdapter = class {
|
|
|
628
598
|
versionMajor: major
|
|
629
599
|
};
|
|
630
600
|
})()
|
|
631
|
-
`);
|
|
632
|
-
if (!result.present || !result.hasDirector) return null;
|
|
633
|
-
const evidence = ["window.cc detected", "cc.director present"];
|
|
634
|
-
if (result.versionMajor === 2) evidence.push("Cocos Creator v2 API");
|
|
635
|
-
else if (result.versionMajor === 3) evidence.push("Cocos Creator v3 API");
|
|
636
|
-
return {
|
|
637
|
-
engine: this.engine,
|
|
638
|
-
version: result.version,
|
|
639
|
-
confidence: .95,
|
|
640
|
-
evidence,
|
|
641
|
-
adapterId: this.id
|
|
642
|
-
};
|
|
643
|
-
} catch {
|
|
644
|
-
return null;
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
async dumpScene(env, opts) {
|
|
648
|
-
const payload = buildCocosSceneTreeDumpPayload(opts);
|
|
649
|
-
const raw = await env.pageController.evaluate(payload);
|
|
650
|
-
return {
|
|
651
|
-
engine: raw.engine,
|
|
652
|
-
version: raw.version,
|
|
653
|
-
canvas: raw.canvas,
|
|
654
|
-
sceneTree: raw.sceneTree ?? {
|
|
655
|
-
id: "empty",
|
|
656
|
-
type: "Scene",
|
|
657
|
-
visible: true,
|
|
658
|
-
interactive: false,
|
|
659
|
-
alpha: 1,
|
|
660
|
-
x: 0,
|
|
661
|
-
y: 0,
|
|
662
|
-
width: raw.canvas?.width ?? 0,
|
|
663
|
-
height: raw.canvas?.height ?? 0,
|
|
664
|
-
worldBounds: {
|
|
665
|
-
x: 0,
|
|
666
|
-
y: 0,
|
|
667
|
-
width: raw.canvas?.width ?? 0,
|
|
668
|
-
height: raw.canvas?.height ?? 0
|
|
669
|
-
},
|
|
670
|
-
path: "cc.director.getScene()"
|
|
671
|
-
},
|
|
672
|
-
totalNodes: raw.totalNodes,
|
|
673
|
-
completeness: raw.completeness === "full" ? "full" : "partial"
|
|
674
|
-
};
|
|
675
|
-
}
|
|
676
|
-
async pickAt(env, opts) {
|
|
677
|
-
const payload = buildCocosHitTestPayload(opts);
|
|
678
|
-
const result = await env.pageController.evaluate(payload);
|
|
679
|
-
return {
|
|
680
|
-
success: result.success,
|
|
681
|
-
picked: result.picked,
|
|
682
|
-
candidates: result.candidates,
|
|
683
|
-
coordinates: result.coordinates,
|
|
684
|
-
hitTestMethod: result.hitTestMethod
|
|
685
|
-
};
|
|
686
|
-
}
|
|
687
|
-
};
|
|
688
|
-
//#endregion
|
|
689
|
-
//#region src/server/domains/canvas/adapters/laya-adapter.ts
|
|
690
|
-
/**
|
|
691
|
-
* Generates a self-contained JS string that traverses Laya.stage via DFS and
|
|
692
|
-
* returns a serialisable scene tree with worldBounds computed via localToGlobal().
|
|
693
|
-
*
|
|
694
|
-
* @param opts - Dump options (maxDepth, onlyInteractive, onlyVisible)
|
|
695
|
-
*/
|
|
696
|
-
function buildLayaSceneTreeDumpPayload(opts) {
|
|
697
|
-
const maxDepth = opts.maxDepth ?? 20;
|
|
698
|
-
const onlyInteractive = opts.onlyInteractive ?? false;
|
|
699
|
-
return `(function() {
|
|
601
|
+
`);if(!t.present||!t.hasDirector)return null;let n=[`window.cc detected`,`cc.director present`];return t.versionMajor===2?n.push(`Cocos Creator v2 API`):t.versionMajor===3&&n.push(`Cocos Creator v3 API`),{engine:this.engine,version:t.version,confidence:.95,evidence:n,adapterId:this.id}}catch{return null}}async dumpScene(e,t){let r=n(t),i=await e.pageController.evaluate(r);return{engine:i.engine,version:i.version,canvas:i.canvas,sceneTree:i.sceneTree??{id:`empty`,type:`Scene`,visible:!0,interactive:!1,alpha:1,x:0,y:0,width:i.canvas?.width??0,height:i.canvas?.height??0,worldBounds:{x:0,y:0,width:i.canvas?.width??0,height:i.canvas?.height??0},path:`cc.director.getScene()`},totalNodes:i.totalNodes,completeness:i.completeness===`full`?`full`:`partial`}}async pickAt(e,t){let n=r(t),i=await e.pageController.evaluate(n);return{success:i.success,picked:i.picked,candidates:i.candidates,coordinates:i.coordinates,hitTestMethod:i.hitTestMethod}}};function a(e){let t=e.maxDepth??20,n=e.onlyInteractive??!1;return`(function() {
|
|
700
602
|
function getChildren(node) {
|
|
701
603
|
if (!node) return [];
|
|
702
604
|
if (node.children && node.numChildren !== undefined) return node.children;
|
|
@@ -740,14 +642,14 @@ function buildLayaSceneTreeDumpPayload(opts) {
|
|
|
740
642
|
var totalNodes = 0;
|
|
741
643
|
|
|
742
644
|
function traverse(node, depth, path) {
|
|
743
|
-
if (!node || depth > ${
|
|
645
|
+
if (!node || depth > ${t}) return null;
|
|
744
646
|
totalNodes++;
|
|
745
647
|
|
|
746
648
|
var interactive = !!(safeProp(node, 'mouseEnabled', true));
|
|
747
649
|
var visible = !!(safeProp(node, 'visible', true));
|
|
748
650
|
|
|
749
|
-
if (${
|
|
750
|
-
if (${
|
|
651
|
+
if (${e.onlyVisible??!1} && !visible) return null;
|
|
652
|
+
if (${n} && !interactive) return null;
|
|
751
653
|
|
|
752
654
|
var wb = localToGlobalRect(node);
|
|
753
655
|
var numC = getNumChildren(node);
|
|
@@ -829,21 +731,7 @@ function buildLayaSceneTreeDumpPayload(opts) {
|
|
|
829
731
|
completeness: 'full',
|
|
830
732
|
_meta: { isLaya3: isLaya3, scaleX: scaleX, scaleY: scaleY }
|
|
831
733
|
};
|
|
832
|
-
})()
|
|
833
|
-
}
|
|
834
|
-
/**
|
|
835
|
-
* Generates a self-contained JS string that:
|
|
836
|
-
* 1. Transforms screen coordinates → stage coordinates using clientScaleX/Y
|
|
837
|
-
* 2. Runs hit test via Stage.hitTest (3.x) or recursive DFS bounds check (2.x)
|
|
838
|
-
* 3. Returns all candidates sorted by depth (topmost first)
|
|
839
|
-
*
|
|
840
|
-
* @param opts - Pick options (x, y, canvasId)
|
|
841
|
-
*/
|
|
842
|
-
function buildLayaHitTestPayload(opts) {
|
|
843
|
-
const x = opts.x;
|
|
844
|
-
const y = opts.y;
|
|
845
|
-
const canvasId = opts.canvasId;
|
|
846
|
-
return `(function() {
|
|
734
|
+
})()`}function o(e){let t=e.x,n=e.y,r=e.canvasId;return`(function() {
|
|
847
735
|
function getChildren(node) {
|
|
848
736
|
if (!node) return [];
|
|
849
737
|
if (node.children && node.numChildren !== undefined) return node.children;
|
|
@@ -896,12 +784,12 @@ function buildLayaHitTestPayload(opts) {
|
|
|
896
784
|
return parts.join('/');
|
|
897
785
|
}
|
|
898
786
|
|
|
899
|
-
var sx = ${
|
|
787
|
+
var sx = ${t}, sy = ${n};
|
|
900
788
|
|
|
901
789
|
// Find the target canvas
|
|
902
790
|
var canvases = Array.from(document.querySelectorAll('canvas'));
|
|
903
791
|
var targetCanvas = null;
|
|
904
|
-
${
|
|
792
|
+
${r?`targetCanvas = document.getElementById(${JSON.stringify(r)}) || canvases[parseInt(${JSON.stringify(r)})] || null;`:`
|
|
905
793
|
for (var ci = canvases.length - 1; ci >= 0; ci--) {
|
|
906
794
|
var r = canvases[ci].getBoundingClientRect();
|
|
907
795
|
if (sx >= r.left && sx <= r.right && sy >= r.top && sy <= r.bottom) {
|
|
@@ -1030,24 +918,7 @@ function buildLayaHitTestPayload(opts) {
|
|
|
1030
918
|
},
|
|
1031
919
|
hitTestMethod: finalMethod
|
|
1032
920
|
};
|
|
1033
|
-
})()`;
|
|
1034
|
-
}
|
|
1035
|
-
/**
|
|
1036
|
-
* LayaAir canvas engine adapter.
|
|
1037
|
-
*
|
|
1038
|
-
* Handles both LayaAir 2.x and 3.x. Version is resolved lazily from window.Laya.version
|
|
1039
|
-
* at first detect() call.
|
|
1040
|
-
*/
|
|
1041
|
-
var LayaCanvasAdapter = class {
|
|
1042
|
-
id = "laya";
|
|
1043
|
-
engine = "LayaAir";
|
|
1044
|
-
version;
|
|
1045
|
-
constructor() {
|
|
1046
|
-
this.version = void 0;
|
|
1047
|
-
}
|
|
1048
|
-
async detect(env) {
|
|
1049
|
-
try {
|
|
1050
|
-
const result = await env.pageController.evaluate(`
|
|
921
|
+
})()`}var s=class{id=`laya`;engine=`LayaAir`;version;constructor(){this.version=void 0}async detect(e){try{let t=await e.pageController.evaluate(`
|
|
1051
922
|
(function() {
|
|
1052
923
|
if (typeof window.Laya === 'undefined' || window.Laya === null) {
|
|
1053
924
|
return { present: false, hasStage: false, laya2: false, laya3: false };
|
|
@@ -1060,72 +931,7 @@ var LayaCanvasAdapter = class {
|
|
|
1060
931
|
return { present: true, hasStage: hasStage, version: version,
|
|
1061
932
|
laya2: laya2, laya3: laya3 };
|
|
1062
933
|
})()
|
|
1063
|
-
`);
|
|
1064
|
-
if (!result.present || !result.hasStage) return null;
|
|
1065
|
-
const evidence = ["window.Laya is defined"];
|
|
1066
|
-
if (result.laya2) evidence.push("Laya.MouseManager detected (LayaAir 2.x)");
|
|
1067
|
-
if (result.laya3) evidence.push("Laya.InputManager detected (LayaAir 3.x)");
|
|
1068
|
-
evidence.push("Laya.stage is present");
|
|
1069
|
-
return {
|
|
1070
|
-
engine: this.engine,
|
|
1071
|
-
version: result.version,
|
|
1072
|
-
confidence: .95,
|
|
1073
|
-
evidence,
|
|
1074
|
-
adapterId: this.id
|
|
1075
|
-
};
|
|
1076
|
-
} catch {
|
|
1077
|
-
return null;
|
|
1078
|
-
}
|
|
1079
|
-
}
|
|
1080
|
-
async dumpScene(env, opts) {
|
|
1081
|
-
const payload = buildLayaSceneTreeDumpPayload(opts);
|
|
1082
|
-
const raw = await env.pageController.evaluate(payload);
|
|
1083
|
-
return {
|
|
1084
|
-
engine: raw.engine,
|
|
1085
|
-
version: raw.version,
|
|
1086
|
-
canvas: raw.canvas,
|
|
1087
|
-
sceneTree: raw.sceneTree ?? {
|
|
1088
|
-
id: "empty",
|
|
1089
|
-
type: "Stage",
|
|
1090
|
-
visible: true,
|
|
1091
|
-
interactive: false,
|
|
1092
|
-
alpha: 1,
|
|
1093
|
-
x: 0,
|
|
1094
|
-
y: 0,
|
|
1095
|
-
width: raw.canvas?.width ?? 0,
|
|
1096
|
-
height: raw.canvas?.height ?? 0,
|
|
1097
|
-
worldBounds: {
|
|
1098
|
-
x: 0,
|
|
1099
|
-
y: 0,
|
|
1100
|
-
width: raw.canvas?.width ?? 0,
|
|
1101
|
-
height: raw.canvas?.height ?? 0
|
|
1102
|
-
},
|
|
1103
|
-
path: "Laya.stage"
|
|
1104
|
-
},
|
|
1105
|
-
totalNodes: raw.totalNodes,
|
|
1106
|
-
completeness: raw.completeness === "full" ? "full" : "partial"
|
|
1107
|
-
};
|
|
1108
|
-
}
|
|
1109
|
-
async pickAt(env, opts) {
|
|
1110
|
-
const payload = buildLayaHitTestPayload(opts);
|
|
1111
|
-
const result = await env.pageController.evaluate(payload);
|
|
1112
|
-
return {
|
|
1113
|
-
success: result.success,
|
|
1114
|
-
picked: result.picked,
|
|
1115
|
-
candidates: result.candidates,
|
|
1116
|
-
coordinates: result.coordinates,
|
|
1117
|
-
hitTestMethod: result.hitTestMethod
|
|
1118
|
-
};
|
|
1119
|
-
}
|
|
1120
|
-
async traceClick(env, opts, services) {
|
|
1121
|
-
const { debuggerManager, traceRecorder, evidenceStore } = services;
|
|
1122
|
-
let traceId = "no-recording";
|
|
1123
|
-
try {
|
|
1124
|
-
traceId = (await traceRecorder.start(null, null, { recordMemoryDeltas: false })).sessionId;
|
|
1125
|
-
} catch {}
|
|
1126
|
-
await debuggerManager.enable();
|
|
1127
|
-
await debuggerManager.ensureAdvancedFeatures();
|
|
1128
|
-
const patchResult = await env.pageController.evaluate(`
|
|
934
|
+
`);if(!t.present||!t.hasStage)return null;let n=[`window.Laya is defined`];return t.laya2&&n.push(`Laya.MouseManager detected (LayaAir 2.x)`),t.laya3&&n.push(`Laya.InputManager detected (LayaAir 3.x)`),n.push(`Laya.stage is present`),{engine:this.engine,version:t.version,confidence:.95,evidence:n,adapterId:this.id}}catch{return null}}async dumpScene(e,t){let n=a(t),r=await e.pageController.evaluate(n);return{engine:r.engine,version:r.version,canvas:r.canvas,sceneTree:r.sceneTree??{id:`empty`,type:`Stage`,visible:!0,interactive:!1,alpha:1,x:0,y:0,width:r.canvas?.width??0,height:r.canvas?.height??0,worldBounds:{x:0,y:0,width:r.canvas?.width??0,height:r.canvas?.height??0},path:`Laya.stage`},totalNodes:r.totalNodes,completeness:r.completeness===`full`?`full`:`partial`}}async pickAt(e,t){let n=o(t),r=await e.pageController.evaluate(n);return{success:r.success,picked:r.picked,candidates:r.candidates,coordinates:r.coordinates,hitTestMethod:r.hitTestMethod}}async traceClick(e,t,n){let{debuggerManager:r,traceRecorder:i,evidenceStore:a}=n,o=`no-recording`;try{o=(await i.start(null,null,{recordMemoryDeltas:!1})).sessionId}catch{}await r.enable(),await r.ensureAdvancedFeatures();let s=await e.pageController.evaluate(`
|
|
1129
935
|
(function() {
|
|
1130
936
|
var k = Symbol.for('__laya_event_patched');
|
|
1131
937
|
var instrumented = [];
|
|
@@ -1162,70 +968,19 @@ var LayaCanvasAdapter = class {
|
|
|
1162
968
|
|
|
1163
969
|
return { success: true, instrumented: instrumented };
|
|
1164
970
|
})()
|
|
1165
|
-
`);
|
|
1166
|
-
const breakpointType = opts.breakpointType ?? "click";
|
|
1167
|
-
await debuggerManager.getEventManager().setEventListenerBreakpoint(breakpointType);
|
|
1168
|
-
const domEventChain = await env.pageController.evaluate(`
|
|
971
|
+
`),c=t.breakpointType??`click`;await r.getEventManager().setEventListenerBreakpoint(c);let l=await e.pageController.evaluate(`
|
|
1169
972
|
(function() {
|
|
1170
|
-
var ev = new PointerEvent(${JSON.stringify(
|
|
973
|
+
var ev = new PointerEvent(${JSON.stringify(c)}, {
|
|
1171
974
|
view: window, bubbles: true, cancelable: true,
|
|
1172
|
-
clientX: ${
|
|
975
|
+
clientX: ${t.targetNodeId??0}, clientY: 0, pointerId: 1
|
|
1173
976
|
});
|
|
1174
977
|
var events = [];
|
|
1175
978
|
var el = document.elementFromPoint(0, 0);
|
|
1176
979
|
if (el) el.dispatchEvent(ev);
|
|
1177
|
-
events.push(${JSON.stringify(
|
|
980
|
+
events.push(${JSON.stringify(c)});
|
|
1178
981
|
return events;
|
|
1179
982
|
})()
|
|
1180
|
-
`);
|
|
1181
|
-
const pausedState = await debuggerManager.waitForPaused(5e3);
|
|
1182
|
-
const handlerFrames = pausedState?.callFrames ? pausedState.callFrames.slice(0, opts.maxFrames ?? 50).map((f) => ({
|
|
1183
|
-
functionName: f.functionName || "(anonymous)",
|
|
1184
|
-
scriptUrl: f.url,
|
|
1185
|
-
lineNumber: f.location?.lineNumber,
|
|
1186
|
-
columnNumber: f.location?.columnNumber
|
|
1187
|
-
})) : [];
|
|
1188
|
-
await debuggerManager.resume();
|
|
1189
|
-
evidenceStore.addNode("function", `laya-click-trace:${traceId}`, {
|
|
1190
|
-
engine: this.engine,
|
|
1191
|
-
version: this.version,
|
|
1192
|
-
handlersFound: handlerFrames.length,
|
|
1193
|
-
instrumentedPrototypes: patchResult?.instrumented ?? []
|
|
1194
|
-
});
|
|
1195
|
-
try {
|
|
1196
|
-
await traceRecorder.stop();
|
|
1197
|
-
} catch {}
|
|
1198
|
-
return {
|
|
1199
|
-
inputFlow: domEventChain,
|
|
1200
|
-
hitTarget: null,
|
|
1201
|
-
domEventChain: handlerFrames.map((f) => ({
|
|
1202
|
-
type: breakpointType,
|
|
1203
|
-
target: f.scriptUrl,
|
|
1204
|
-
phase: "at-target"
|
|
1205
|
-
})),
|
|
1206
|
-
engineDispatchChain: patchResult?.instrumented ?? [],
|
|
1207
|
-
handlerFrames,
|
|
1208
|
-
handlersTriggered: handlerFrames.map((f) => ({
|
|
1209
|
-
functionName: f.functionName,
|
|
1210
|
-
scriptUrl: f.scriptUrl,
|
|
1211
|
-
lineNumber: f.lineNumber
|
|
1212
|
-
})),
|
|
1213
|
-
networkEmitted: []
|
|
1214
|
-
};
|
|
1215
|
-
}
|
|
1216
|
-
};
|
|
1217
|
-
//#endregion
|
|
1218
|
-
//#region src/server/domains/canvas/adapters/phaser-adapter.ts
|
|
1219
|
-
/**
|
|
1220
|
-
* Generates a self-contained JS string that traverses Phaser scenes via DFS and
|
|
1221
|
-
* returns a serialisable scene tree with worldBounds computed via getBounds().
|
|
1222
|
-
*
|
|
1223
|
-
* @param opts - Dump options (maxDepth, onlyInteractive, onlyVisible)
|
|
1224
|
-
*/
|
|
1225
|
-
function buildPhaserSceneTreeDumpPayload(opts) {
|
|
1226
|
-
const maxDepth = opts.maxDepth ?? 20;
|
|
1227
|
-
const onlyInteractive = opts.onlyInteractive ?? false;
|
|
1228
|
-
return `(function() {
|
|
983
|
+
`),u=await r.waitForPaused(5e3),d=u?.callFrames?u.callFrames.slice(0,t.maxFrames??50).map(e=>({functionName:e.functionName||`(anonymous)`,scriptUrl:e.url,lineNumber:e.location?.lineNumber,columnNumber:e.location?.columnNumber})):[];await r.resume(),a.addNode(`function`,`laya-click-trace:${o}`,{engine:this.engine,version:this.version,handlersFound:d.length,instrumentedPrototypes:s?.instrumented??[]});try{await i.stop()}catch{}return{inputFlow:l,hitTarget:null,domEventChain:d.map(e=>({type:c,target:e.scriptUrl,phase:`at-target`})),engineDispatchChain:s?.instrumented??[],handlerFrames:d,handlersTriggered:d.map(e=>({functionName:e.functionName,scriptUrl:e.scriptUrl,lineNumber:e.lineNumber})),networkEmitted:[]}}};function c(e){let t=e.maxDepth??20,n=e.onlyInteractive??!1;return`(function() {
|
|
1229
984
|
function getChildren(node) {
|
|
1230
985
|
if (!node) return [];
|
|
1231
986
|
if (node.list && Array.isArray(node.list)) return node.list;
|
|
@@ -1269,14 +1024,14 @@ function buildPhaserSceneTreeDumpPayload(opts) {
|
|
|
1269
1024
|
var totalNodes = 0;
|
|
1270
1025
|
|
|
1271
1026
|
function traverse(node, depth, path) {
|
|
1272
|
-
if (!node || depth > ${
|
|
1027
|
+
if (!node || depth > ${t}) return null;
|
|
1273
1028
|
totalNodes++;
|
|
1274
1029
|
|
|
1275
1030
|
var interactive = !!(node.input && node.input.enabled);
|
|
1276
1031
|
var visible = !!(safeProp(node, 'visible', true));
|
|
1277
1032
|
|
|
1278
|
-
if (${
|
|
1279
|
-
if (${
|
|
1033
|
+
if (${e.onlyVisible??!1} && !visible) return null;
|
|
1034
|
+
if (${n} && !interactive) return null;
|
|
1280
1035
|
|
|
1281
1036
|
var wb = nodeBounds(node);
|
|
1282
1037
|
var numC = getNumChildren(node);
|
|
@@ -1372,22 +1127,7 @@ function buildPhaserSceneTreeDumpPayload(opts) {
|
|
|
1372
1127
|
totalNodes: totalNodes,
|
|
1373
1128
|
completeness: sceneTree ? 'full' : 'partial',
|
|
1374
1129
|
};
|
|
1375
|
-
})()
|
|
1376
|
-
}
|
|
1377
|
-
/**
|
|
1378
|
-
* Generates a self-contained JS string that:
|
|
1379
|
-
* 1. Transforms screen coordinates to canvas coordinates
|
|
1380
|
-
* 2. Runs hit test via scene.input.hitTestPointer() (Phaser's native method)
|
|
1381
|
-
* 3. Falls back to recursive bounds check using getBounds() / getTopLeft/getBottomRight
|
|
1382
|
-
* 4. Returns all candidates sorted by depth (topmost first)
|
|
1383
|
-
*
|
|
1384
|
-
* @param opts - Pick options (x, y, canvasId)
|
|
1385
|
-
*/
|
|
1386
|
-
function buildPhaserHitTestPayload(opts) {
|
|
1387
|
-
const x = opts.x;
|
|
1388
|
-
const y = opts.y;
|
|
1389
|
-
const canvasId = opts.canvasId;
|
|
1390
|
-
return `(function() {
|
|
1130
|
+
})()`}function l(e){let t=e.x,n=e.y,r=e.canvasId;return`(function() {
|
|
1391
1131
|
function getChildren(node) {
|
|
1392
1132
|
if (!node) return [];
|
|
1393
1133
|
if (node.list && Array.isArray(node.list)) return node.list;
|
|
@@ -1439,12 +1179,12 @@ function buildPhaserHitTestPayload(opts) {
|
|
|
1439
1179
|
return 'Phaser.Game.scenes[' + sceneIdx + ']/' + parts.join('/');
|
|
1440
1180
|
}
|
|
1441
1181
|
|
|
1442
|
-
var sx = ${
|
|
1182
|
+
var sx = ${t}, sy = ${n};
|
|
1443
1183
|
|
|
1444
1184
|
// Find the target canvas
|
|
1445
1185
|
var canvases = Array.from(document.querySelectorAll('canvas'));
|
|
1446
1186
|
var targetCanvas = null;
|
|
1447
|
-
${
|
|
1187
|
+
${r?`targetCanvas = document.getElementById(${JSON.stringify(r)}) || canvases[parseInt(${JSON.stringify(r)})] || null;`:`
|
|
1448
1188
|
for (var ci = canvases.length - 1; ci >= 0; ci--) {
|
|
1449
1189
|
var r = canvases[ci].getBoundingClientRect();
|
|
1450
1190
|
if (sx >= r.left && sx <= r.right && sy >= r.top && sy <= r.bottom) {
|
|
@@ -1600,25 +1340,7 @@ function buildPhaserHitTestPayload(opts) {
|
|
|
1600
1340
|
},
|
|
1601
1341
|
hitTestMethod: hitTestMethod
|
|
1602
1342
|
};
|
|
1603
|
-
})()`;
|
|
1604
|
-
}
|
|
1605
|
-
/**
|
|
1606
|
-
* Phaser 3.x canvas engine adapter.
|
|
1607
|
-
*
|
|
1608
|
-
* Detection checks window.Phaser and Phaser.GAMES.length > 0.
|
|
1609
|
-
* dumpScene() traverses Phaser.GAMES[0].scene.scenes active scenes.
|
|
1610
|
-
* pickAt() uses scene.input.hitTestPointer() with recursive DFS fallback.
|
|
1611
|
-
*/
|
|
1612
|
-
var PhaserCanvasAdapter = class {
|
|
1613
|
-
id = "phaser";
|
|
1614
|
-
engine = "Phaser";
|
|
1615
|
-
version;
|
|
1616
|
-
constructor() {
|
|
1617
|
-
this.version = void 0;
|
|
1618
|
-
}
|
|
1619
|
-
async detect(env) {
|
|
1620
|
-
try {
|
|
1621
|
-
const result = await env.pageController.evaluate(`
|
|
1343
|
+
})()`}var u=class{id=`phaser`;engine=`Phaser`;version;constructor(){this.version=void 0}async detect(e){try{let t=await e.pageController.evaluate(`
|
|
1622
1344
|
(function() {
|
|
1623
1345
|
if (typeof window.Phaser === 'undefined' || window.Phaser === null) {
|
|
1624
1346
|
return { present: false, hasGames: false };
|
|
@@ -1630,76 +1352,7 @@ var PhaserCanvasAdapter = class {
|
|
|
1630
1352
|
version: window.Phaser.VERSION || undefined,
|
|
1631
1353
|
};
|
|
1632
1354
|
})()
|
|
1633
|
-
`);
|
|
1634
|
-
if (!result.present || !result.hasGames) return null;
|
|
1635
|
-
const evidence = ["window.Phaser detected"];
|
|
1636
|
-
evidence.push("Phaser.GAMES has entries");
|
|
1637
|
-
return {
|
|
1638
|
-
engine: this.engine,
|
|
1639
|
-
version: result.version,
|
|
1640
|
-
confidence: .95,
|
|
1641
|
-
evidence,
|
|
1642
|
-
adapterId: this.id
|
|
1643
|
-
};
|
|
1644
|
-
} catch {
|
|
1645
|
-
return null;
|
|
1646
|
-
}
|
|
1647
|
-
}
|
|
1648
|
-
async dumpScene(env, opts) {
|
|
1649
|
-
const payload = buildPhaserSceneTreeDumpPayload(opts);
|
|
1650
|
-
const raw = await env.pageController.evaluate(payload);
|
|
1651
|
-
return {
|
|
1652
|
-
engine: raw.engine,
|
|
1653
|
-
version: raw.version,
|
|
1654
|
-
canvas: raw.canvas,
|
|
1655
|
-
sceneTree: raw.sceneTree ?? {
|
|
1656
|
-
id: "empty",
|
|
1657
|
-
type: "Game",
|
|
1658
|
-
visible: true,
|
|
1659
|
-
interactive: false,
|
|
1660
|
-
alpha: 1,
|
|
1661
|
-
x: 0,
|
|
1662
|
-
y: 0,
|
|
1663
|
-
width: raw.canvas?.width ?? 0,
|
|
1664
|
-
height: raw.canvas?.height ?? 0,
|
|
1665
|
-
worldBounds: {
|
|
1666
|
-
x: 0,
|
|
1667
|
-
y: 0,
|
|
1668
|
-
width: raw.canvas?.width ?? 0,
|
|
1669
|
-
height: raw.canvas?.height ?? 0
|
|
1670
|
-
},
|
|
1671
|
-
path: "Phaser.Game"
|
|
1672
|
-
},
|
|
1673
|
-
totalNodes: raw.totalNodes,
|
|
1674
|
-
completeness: raw.completeness === "full" ? "full" : "partial"
|
|
1675
|
-
};
|
|
1676
|
-
}
|
|
1677
|
-
async pickAt(env, opts) {
|
|
1678
|
-
const payload = buildPhaserHitTestPayload(opts);
|
|
1679
|
-
const result = await env.pageController.evaluate(payload);
|
|
1680
|
-
return {
|
|
1681
|
-
success: result.success,
|
|
1682
|
-
picked: result.picked,
|
|
1683
|
-
candidates: result.candidates,
|
|
1684
|
-
coordinates: result.coordinates,
|
|
1685
|
-
hitTestMethod: result.hitTestMethod
|
|
1686
|
-
};
|
|
1687
|
-
}
|
|
1688
|
-
};
|
|
1689
|
-
//#endregion
|
|
1690
|
-
//#region src/server/domains/canvas/adapters/pixi-adapter.ts
|
|
1691
|
-
/**
|
|
1692
|
-
* Generates a self-contained JS string that traverses the PIXI scene graph via DFS
|
|
1693
|
-
* and returns a serialisable scene tree with worldBounds computed via getBounds().
|
|
1694
|
-
*
|
|
1695
|
-
* Handles both PIXI v7 (interactive property) and v8 (eventMode property).
|
|
1696
|
-
*
|
|
1697
|
-
* @param opts - Dump options (maxDepth, onlyInteractive, onlyVisible)
|
|
1698
|
-
*/
|
|
1699
|
-
function buildPixiSceneTreeDumpPayload(opts) {
|
|
1700
|
-
const maxDepth = opts.maxDepth ?? 20;
|
|
1701
|
-
const onlyInteractive = opts.onlyInteractive ?? false;
|
|
1702
|
-
return `(function() {
|
|
1355
|
+
`);if(!t.present||!t.hasGames)return null;let n=[`window.Phaser detected`];return n.push(`Phaser.GAMES has entries`),{engine:this.engine,version:t.version,confidence:.95,evidence:n,adapterId:this.id}}catch{return null}}async dumpScene(e,t){let n=c(t),r=await e.pageController.evaluate(n);return{engine:r.engine,version:r.version,canvas:r.canvas,sceneTree:r.sceneTree??{id:`empty`,type:`Game`,visible:!0,interactive:!1,alpha:1,x:0,y:0,width:r.canvas?.width??0,height:r.canvas?.height??0,worldBounds:{x:0,y:0,width:r.canvas?.width??0,height:r.canvas?.height??0},path:`Phaser.Game`},totalNodes:r.totalNodes,completeness:r.completeness===`full`?`full`:`partial`}}async pickAt(e,t){let n=l(t),r=await e.pageController.evaluate(n);return{success:r.success,picked:r.picked,candidates:r.candidates,coordinates:r.coordinates,hitTestMethod:r.hitTestMethod}}};function d(e){let t=e.maxDepth??20,n=e.onlyInteractive??!1;return`(function() {
|
|
1703
1356
|
function getChildren(node) {
|
|
1704
1357
|
if (!node) return [];
|
|
1705
1358
|
if (node.children && node.numChildren !== undefined) return node.children;
|
|
@@ -1744,15 +1397,15 @@ function buildPixiSceneTreeDumpPayload(opts) {
|
|
|
1744
1397
|
var totalNodes = 0;
|
|
1745
1398
|
|
|
1746
1399
|
function traverse(node, depth, path) {
|
|
1747
|
-
if (!node || depth > ${
|
|
1400
|
+
if (!node || depth > ${t}) return null;
|
|
1748
1401
|
totalNodes++;
|
|
1749
1402
|
|
|
1750
1403
|
var visible = !!(safeProp(node, 'visible', true));
|
|
1751
1404
|
// PIXI v7 uses 'interactive', v8 uses 'eventMode'
|
|
1752
1405
|
var interactive = !!(safeProp(node, 'interactive', false)) || !!(safeProp(node, 'eventMode', 'none') !== 'none');
|
|
1753
1406
|
|
|
1754
|
-
if (${
|
|
1755
|
-
if (${
|
|
1407
|
+
if (${e.onlyVisible??!1} && !visible) return null;
|
|
1408
|
+
if (${n} && !interactive) return null;
|
|
1756
1409
|
|
|
1757
1410
|
var numC = getNumChildren(node);
|
|
1758
1411
|
var children = null;
|
|
@@ -1850,21 +1503,7 @@ function buildPixiSceneTreeDumpPayload(opts) {
|
|
|
1850
1503
|
totalNodes: totalNodes,
|
|
1851
1504
|
completeness: 'full'
|
|
1852
1505
|
};
|
|
1853
|
-
})()
|
|
1854
|
-
}
|
|
1855
|
-
/**
|
|
1856
|
-
* Generates a self-contained JS string that:
|
|
1857
|
-
* 1. Transforms screen coordinates → canvas coordinates
|
|
1858
|
-
* 2. Runs hit test via Stage.hitTest() if available (PIXI v7+), or DFS with getBounds()
|
|
1859
|
-
* 3. Returns all candidates sorted by depth (topmost first)
|
|
1860
|
-
*
|
|
1861
|
-
* @param opts - Pick options (x, y, canvasId)
|
|
1862
|
-
*/
|
|
1863
|
-
function buildPixiHitTestPayload(opts) {
|
|
1864
|
-
const x = opts.x;
|
|
1865
|
-
const y = opts.y;
|
|
1866
|
-
const canvasId = opts.canvasId;
|
|
1867
|
-
return `(function() {
|
|
1506
|
+
})()`}function f(e){let t=e.x,n=e.y,r=e.canvasId;return`(function() {
|
|
1868
1507
|
function getChildren(node) {
|
|
1869
1508
|
if (!node) return [];
|
|
1870
1509
|
if (node.children && node.numChildren !== undefined) return node.children;
|
|
@@ -1919,12 +1558,12 @@ function buildPixiHitTestPayload(opts) {
|
|
|
1919
1558
|
return parts.join('/');
|
|
1920
1559
|
}
|
|
1921
1560
|
|
|
1922
|
-
var sx = ${
|
|
1561
|
+
var sx = ${t}, sy = ${n};
|
|
1923
1562
|
|
|
1924
1563
|
// Find the target canvas
|
|
1925
1564
|
var canvases = Array.from(document.querySelectorAll('canvas'));
|
|
1926
1565
|
var targetCanvas = null;
|
|
1927
|
-
${
|
|
1566
|
+
${r?`targetCanvas = document.getElementById(${JSON.stringify(r)}) || null;`:`
|
|
1928
1567
|
for (var ci = canvases.length - 1; ci >= 0; ci--) {
|
|
1929
1568
|
var r = canvases[ci].getBoundingClientRect();
|
|
1930
1569
|
if (sx >= r.left && sx <= r.right && sy >= r.top && sy <= r.bottom) {
|
|
@@ -2081,24 +1720,7 @@ function buildPixiHitTestPayload(opts) {
|
|
|
2081
1720
|
},
|
|
2082
1721
|
hitTestMethod: finalMethod
|
|
2083
1722
|
};
|
|
2084
|
-
})()`;
|
|
2085
|
-
}
|
|
2086
|
-
/**
|
|
2087
|
-
* PixiJS canvas engine adapter.
|
|
2088
|
-
*
|
|
2089
|
-
* Handles both PixiJS v7 (interactive) and v8 (eventMode). Version is resolved
|
|
2090
|
-
* lazily from window.PIXI.VERSION at detect() time.
|
|
2091
|
-
*/
|
|
2092
|
-
var PixiJSCanvasAdapter = class {
|
|
2093
|
-
id = "pixi";
|
|
2094
|
-
engine = "PixiJS";
|
|
2095
|
-
version;
|
|
2096
|
-
constructor() {
|
|
2097
|
-
this.version = void 0;
|
|
2098
|
-
}
|
|
2099
|
-
async detect(env) {
|
|
2100
|
-
try {
|
|
2101
|
-
const result = await env.pageController.evaluate(`
|
|
1723
|
+
})()`}var p=class{id=`pixi`;engine=`PixiJS`;version;constructor(){this.version=void 0}async detect(e){try{let t=await e.pageController.evaluate(`
|
|
2102
1724
|
(function() {
|
|
2103
1725
|
if (typeof window.PIXI === 'undefined' || window.PIXI === null) {
|
|
2104
1726
|
return { present: false, hasApp: false };
|
|
@@ -2108,163 +1730,30 @@ var PixiJSCanvasAdapter = class {
|
|
|
2108
1730
|
var version = pixi.VERSION || pixi.version;
|
|
2109
1731
|
return { present: true, hasApp: hasApp, version: version };
|
|
2110
1732
|
})()
|
|
2111
|
-
`);
|
|
2112
|
-
if (!result.present || !result.hasApp) return null;
|
|
2113
|
-
const evidence = ["window.PIXI detected"];
|
|
2114
|
-
if (result.version) evidence.push("PIXI.VERSION: " + result.version);
|
|
2115
|
-
evidence.push("PIXI.Application detected");
|
|
2116
|
-
return {
|
|
2117
|
-
engine: this.engine,
|
|
2118
|
-
version: result.version,
|
|
2119
|
-
confidence: .95,
|
|
2120
|
-
evidence,
|
|
2121
|
-
adapterId: this.id
|
|
2122
|
-
};
|
|
2123
|
-
} catch {
|
|
2124
|
-
return null;
|
|
2125
|
-
}
|
|
2126
|
-
}
|
|
2127
|
-
async dumpScene(env, opts) {
|
|
2128
|
-
const payload = buildPixiSceneTreeDumpPayload(opts);
|
|
2129
|
-
const raw = await env.pageController.evaluate(payload);
|
|
2130
|
-
return {
|
|
2131
|
-
engine: raw.engine,
|
|
2132
|
-
version: raw.version,
|
|
2133
|
-
canvas: raw.canvas,
|
|
2134
|
-
sceneTree: raw.sceneTree ?? {
|
|
2135
|
-
id: "empty",
|
|
2136
|
-
type: "Container",
|
|
2137
|
-
visible: true,
|
|
2138
|
-
interactive: false,
|
|
2139
|
-
alpha: 1,
|
|
2140
|
-
x: 0,
|
|
2141
|
-
y: 0,
|
|
2142
|
-
width: raw.canvas?.width ?? 0,
|
|
2143
|
-
height: raw.canvas?.height ?? 0,
|
|
2144
|
-
worldBounds: {
|
|
2145
|
-
x: 0,
|
|
2146
|
-
y: 0,
|
|
2147
|
-
width: raw.canvas?.width ?? 0,
|
|
2148
|
-
height: raw.canvas?.height ?? 0
|
|
2149
|
-
},
|
|
2150
|
-
path: "PIXI.Application.stage"
|
|
2151
|
-
},
|
|
2152
|
-
totalNodes: raw.totalNodes,
|
|
2153
|
-
completeness: raw.completeness === "full" ? "full" : "partial"
|
|
2154
|
-
};
|
|
2155
|
-
}
|
|
2156
|
-
async pickAt(env, opts) {
|
|
2157
|
-
const payload = buildPixiHitTestPayload(opts);
|
|
2158
|
-
const result = await env.pageController.evaluate(payload);
|
|
2159
|
-
return {
|
|
2160
|
-
success: result.success,
|
|
2161
|
-
picked: result.picked,
|
|
2162
|
-
candidates: result.candidates,
|
|
2163
|
-
coordinates: result.coordinates,
|
|
2164
|
-
hitTestMethod: result.hitTestMethod
|
|
2165
|
-
};
|
|
2166
|
-
}
|
|
2167
|
-
};
|
|
2168
|
-
//#endregion
|
|
2169
|
-
//#region src/server/domains/canvas/handlers/shared.ts
|
|
2170
|
-
/**
|
|
2171
|
-
* Shared utilities for canvas tool handlers.
|
|
2172
|
-
*
|
|
2173
|
-
* Engine anchor patterns, adapter registry, probe env builder, and shared helpers.
|
|
2174
|
-
*/
|
|
2175
|
-
/** Well-known engine global anchors and their adapter IDs. */
|
|
2176
|
-
const ENGINE_ANCHORS = [
|
|
2177
|
-
{
|
|
2178
|
-
pattern: "Laya",
|
|
2179
|
-
adapterId: "laya",
|
|
2180
|
-
engine: "LayaAir"
|
|
2181
|
-
},
|
|
2182
|
-
{
|
|
2183
|
-
pattern: "PIXI",
|
|
2184
|
-
adapterId: "pixi",
|
|
2185
|
-
engine: "PixiJS"
|
|
2186
|
-
},
|
|
2187
|
-
{
|
|
2188
|
-
pattern: "Phaser",
|
|
2189
|
-
adapterId: "phaser",
|
|
2190
|
-
engine: "Phaser"
|
|
2191
|
-
},
|
|
2192
|
-
{
|
|
2193
|
-
pattern: "cc",
|
|
2194
|
-
adapterId: "cocos",
|
|
2195
|
-
engine: "CocosCreator"
|
|
2196
|
-
},
|
|
2197
|
-
{
|
|
2198
|
-
pattern: "legacyCC",
|
|
2199
|
-
adapterId: "cocos",
|
|
2200
|
-
engine: "CocosCreator"
|
|
2201
|
-
},
|
|
2202
|
-
{
|
|
2203
|
-
pattern: "BABYLON",
|
|
2204
|
-
adapterId: "babylon",
|
|
2205
|
-
engine: "Babylon.js"
|
|
2206
|
-
},
|
|
2207
|
-
{
|
|
2208
|
-
pattern: "THREE",
|
|
2209
|
-
adapterId: "three",
|
|
2210
|
-
engine: "Three.js"
|
|
2211
|
-
},
|
|
2212
|
-
{
|
|
2213
|
-
pattern: "createUnityInstance",
|
|
2214
|
-
adapterId: "unity",
|
|
2215
|
-
engine: "UnityWebGL"
|
|
2216
|
-
}
|
|
2217
|
-
];
|
|
2218
|
-
/** Adapter registry — registered per engine. */
|
|
2219
|
-
const adapterRegistry = /* @__PURE__ */ new Map();
|
|
2220
|
-
const adapterFactories = {
|
|
2221
|
-
laya: () => new LayaCanvasAdapter(),
|
|
2222
|
-
pixi: () => new PixiJSCanvasAdapter(),
|
|
2223
|
-
phaser: () => new PhaserCanvasAdapter(),
|
|
2224
|
-
cocos: () => new CocosCanvasAdapter()
|
|
2225
|
-
};
|
|
2226
|
-
function resolveAdapter(detection) {
|
|
2227
|
-
if (!detection) return null;
|
|
2228
|
-
if (adapterRegistry.has(detection.adapterId)) return adapterRegistry.get(detection.adapterId);
|
|
2229
|
-
const factory = adapterFactories[detection.adapterId];
|
|
2230
|
-
if (!factory) return null;
|
|
2231
|
-
const adapter = factory();
|
|
2232
|
-
adapterRegistry.set(detection.adapterId, adapter);
|
|
2233
|
-
return adapter;
|
|
2234
|
-
}
|
|
2235
|
-
function buildEnv(pageController) {
|
|
2236
|
-
return {
|
|
2237
|
-
pageController,
|
|
2238
|
-
cdpSession: null,
|
|
2239
|
-
tabId: "default"
|
|
2240
|
-
};
|
|
2241
|
-
}
|
|
2242
|
-
async function fingerprintCanvas(pageController, canvasId) {
|
|
2243
|
-
try {
|
|
2244
|
-
const result = await pageController.evaluate(`
|
|
1733
|
+
`);if(!t.present||!t.hasApp)return null;let n=[`window.PIXI detected`];return t.version&&n.push(`PIXI.VERSION: `+t.version),n.push(`PIXI.Application detected`),{engine:this.engine,version:t.version,confidence:.95,evidence:n,adapterId:this.id}}catch{return null}}async dumpScene(e,t){let n=d(t),r=await e.pageController.evaluate(n);return{engine:r.engine,version:r.version,canvas:r.canvas,sceneTree:r.sceneTree??{id:`empty`,type:`Container`,visible:!0,interactive:!1,alpha:1,x:0,y:0,width:r.canvas?.width??0,height:r.canvas?.height??0,worldBounds:{x:0,y:0,width:r.canvas?.width??0,height:r.canvas?.height??0},path:`PIXI.Application.stage`},totalNodes:r.totalNodes,completeness:r.completeness===`full`?`full`:`partial`}}async pickAt(e,t){let n=f(t),r=await e.pageController.evaluate(n);return{success:r.success,picked:r.picked,candidates:r.candidates,coordinates:r.coordinates,hitTestMethod:r.hitTestMethod}}};const m=[{pattern:`Laya`,adapterId:`laya`,engine:`LayaAir`},{pattern:`PIXI`,adapterId:`pixi`,engine:`PixiJS`},{pattern:`Phaser`,adapterId:`phaser`,engine:`Phaser`},{pattern:`cc`,adapterId:`cocos`,engine:`CocosCreator`},{pattern:`legacyCC`,adapterId:`cocos`,engine:`CocosCreator`},{pattern:`BABYLON`,adapterId:`babylon`,engine:`Babylon.js`},{pattern:`THREE`,adapterId:`three`,engine:`Three.js`},{pattern:`createUnityInstance`,adapterId:`unity`,engine:`UnityWebGL`}],h=new Map,g={laya:()=>new s,pixi:()=>new p,phaser:()=>new u,cocos:()=>new i};function _(e){if(!e)return null;if(h.has(e.adapterId))return h.get(e.adapterId);let t=g[e.adapterId];if(!t)return null;let n=t();return h.set(e.adapterId,n),n}function v(e){return{pageController:e,cdpSession:null,tabId:`default`}}async function y(e,t){try{let n=await e.evaluate(`
|
|
2245
1734
|
(function() {
|
|
2246
1735
|
const hits = [];
|
|
2247
|
-
${
|
|
1736
|
+
${m.map(({pattern:e,adapterId:t,engine:n})=>`
|
|
2248
1737
|
try {
|
|
2249
|
-
if (window[${JSON.stringify(
|
|
2250
|
-
const v = window[${JSON.stringify(
|
|
1738
|
+
if (window[${JSON.stringify(e)}] !== undefined) {
|
|
1739
|
+
const v = window[${JSON.stringify(e)}];
|
|
2251
1740
|
hits.push({
|
|
2252
|
-
engine: ${JSON.stringify(
|
|
2253
|
-
adapterId: ${JSON.stringify(
|
|
1741
|
+
engine: ${JSON.stringify(n)},
|
|
1742
|
+
adapterId: ${JSON.stringify(t)},
|
|
2254
1743
|
version: v.version || v.VERSION || (v.Laya && v.Laya.version) || undefined
|
|
2255
1744
|
});
|
|
2256
1745
|
}
|
|
2257
1746
|
} catch(e) {}
|
|
2258
|
-
`).join(
|
|
1747
|
+
`).join(``)}
|
|
2259
1748
|
|
|
2260
1749
|
if (hits.length === 0) {
|
|
2261
1750
|
return { hits: hits, selected: null, selectedEvidence: [] };
|
|
2262
1751
|
}
|
|
2263
1752
|
|
|
2264
1753
|
var targetCanvas = null;
|
|
2265
|
-
if (${
|
|
1754
|
+
if (${t!==void 0}) {
|
|
2266
1755
|
var canvases = Array.from(document.querySelectorAll('canvas'));
|
|
2267
|
-
var requestedId = ${JSON.stringify(
|
|
1756
|
+
var requestedId = ${JSON.stringify(t??null)};
|
|
2268
1757
|
var requestedIndex = Number.parseInt(requestedId, 10);
|
|
2269
1758
|
targetCanvas =
|
|
2270
1759
|
document.getElementById(requestedId) ||
|
|
@@ -2307,7 +1796,9 @@ async function fingerprintCanvas(pageController, canvasId) {
|
|
|
2307
1796
|
if (canvasEquals(game.canvas) || canvasEquals(game._canvas)) {
|
|
2308
1797
|
evidence.push('target canvas matches cc.game canvas');
|
|
2309
1798
|
}
|
|
2310
|
-
if (game.container && typeof game.container.contains === 'function' &&
|
|
1799
|
+
if (game.container && typeof game.container.contains === 'function' &&
|
|
1800
|
+
game.container.contains(targetCanvas))
|
|
1801
|
+
{
|
|
2311
1802
|
evidence.push('target canvas is inside cc.game.container');
|
|
2312
1803
|
}
|
|
2313
1804
|
}
|
|
@@ -2316,10 +1807,14 @@ async function fingerprintCanvas(pageController, canvasId) {
|
|
|
2316
1807
|
if (adapterId === 'laya' && window.Laya) {
|
|
2317
1808
|
var candidates = [
|
|
2318
1809
|
window.Laya.Browser && window.Laya.Browser.canvas,
|
|
2319
|
-
window.Laya.Render && window.Laya.Render._mainCanvas &&
|
|
2320
|
-
|
|
2321
|
-
window.Laya.
|
|
2322
|
-
|
|
1810
|
+
window.Laya.Render && window.Laya.Render._mainCanvas &&
|
|
1811
|
+
(window.Laya.Render._mainCanvas.source || window.Laya.Render._mainCanvas._source || window.Laya.Render._mainCanvas),
|
|
1812
|
+
window.Laya.Render && window.Laya.Render._context && window.Laya.Render._context.canvas &&
|
|
1813
|
+
(window.Laya.Render._context.canvas.source || window.Laya.Render._context.canvas),
|
|
1814
|
+
window.Laya.stage && window.Laya.stage._canvas &&
|
|
1815
|
+
(window.Laya.stage._canvas.source || window.Laya.stage._canvas._source || window.Laya.stage._canvas),
|
|
1816
|
+
window.Laya.stage && window.Laya.stage.canvas &&
|
|
1817
|
+
(window.Laya.stage.canvas.source || window.Laya.stage.canvas._source || window.Laya.stage.canvas)
|
|
2323
1818
|
].filter(Boolean);
|
|
2324
1819
|
if (candidates.some(canvasEquals)) {
|
|
2325
1820
|
evidence.push('target canvas matches Laya render canvas');
|
|
@@ -2342,53 +1837,26 @@ async function fingerprintCanvas(pageController, canvasId) {
|
|
|
2342
1837
|
|
|
2343
1838
|
return { hits: hits, selected: hits[0] || null, selectedEvidence: [] };
|
|
2344
1839
|
})()
|
|
2345
|
-
`);
|
|
2346
|
-
if (!result.selected) return null;
|
|
2347
|
-
const hit = result.selected;
|
|
2348
|
-
return {
|
|
2349
|
-
engine: hit.engine,
|
|
2350
|
-
version: hit.version,
|
|
2351
|
-
confidence: result.selectedEvidence.length > 0 ? .95 : .9,
|
|
2352
|
-
evidence: ["window global detected", ...result.selectedEvidence],
|
|
2353
|
-
adapterId: hit.adapterId
|
|
2354
|
-
};
|
|
2355
|
-
} catch {
|
|
2356
|
-
return null;
|
|
2357
|
-
}
|
|
2358
|
-
}
|
|
2359
|
-
//#endregion
|
|
2360
|
-
//#region src/server/domains/canvas/handlers/fingerprint.ts
|
|
2361
|
-
async function handleFingerprint(pageController, args) {
|
|
2362
|
-
const canvasId = args["canvasId"];
|
|
2363
|
-
const globalScan = await pageController.evaluate(`
|
|
1840
|
+
`);if(!n.selected)return null;let r=n.selected;return{engine:r.engine,version:r.version,confidence:n.selectedEvidence.length>0?.95:.9,evidence:[`window global detected`,...n.selectedEvidence],adapterId:r.adapterId}}catch{return null}}async function b(e,t){let n=t.canvasId,r=await e.evaluate(`
|
|
2364
1841
|
(function() {
|
|
2365
1842
|
const results = [];
|
|
2366
|
-
${
|
|
1843
|
+
${m.map(({pattern:e,adapterId:t,engine:n})=>`
|
|
2367
1844
|
try {
|
|
2368
|
-
const global = window[${JSON.stringify(
|
|
1845
|
+
const global = window[${JSON.stringify(e)}];
|
|
2369
1846
|
if (global !== undefined) {
|
|
2370
1847
|
results.push({
|
|
2371
|
-
pattern: ${JSON.stringify(
|
|
2372
|
-
adapterId: ${JSON.stringify(
|
|
2373
|
-
engine: ${JSON.stringify(
|
|
1848
|
+
pattern: ${JSON.stringify(e)},
|
|
1849
|
+
adapterId: ${JSON.stringify(t)},
|
|
1850
|
+
engine: ${JSON.stringify(n)},
|
|
2374
1851
|
present: true,
|
|
2375
1852
|
version: (global.version || global.VERSION || global.Laya?.version || undefined)
|
|
2376
1853
|
});
|
|
2377
1854
|
}
|
|
2378
1855
|
} catch(e) {}
|
|
2379
|
-
`).join(
|
|
1856
|
+
`).join(``)}
|
|
2380
1857
|
return results;
|
|
2381
1858
|
})()
|
|
2382
|
-
`);
|
|
2383
|
-
const candidates = [];
|
|
2384
|
-
for (const hit of globalScan) candidates.push({
|
|
2385
|
-
engine: hit.engine,
|
|
2386
|
-
version: hit.version,
|
|
2387
|
-
confidence: .9,
|
|
2388
|
-
evidence: [`global window.${hit.pattern} is defined`],
|
|
2389
|
-
adapterId: hit.adapterId
|
|
2390
|
-
});
|
|
2391
|
-
const canvasInfo = await pageController.evaluate(`
|
|
1859
|
+
`),i=[];for(let e of r)i.push({engine:e.engine,version:e.version,confidence:.9,evidence:[`global window.${e.pattern} is defined`],adapterId:e.adapterId});let a=await e.evaluate(`
|
|
2392
1860
|
(function() {
|
|
2393
1861
|
return Array.from(document.querySelectorAll('canvas')).map(function(c) {
|
|
2394
1862
|
var ctx = c.getContext('webgl2') || c.getContext('webgl') || c.getContext('2d');
|
|
@@ -2407,41 +1875,10 @@ async function handleFingerprint(pageController, args) {
|
|
|
2407
1875
|
return info;
|
|
2408
1876
|
});
|
|
2409
1877
|
})()
|
|
2410
|
-
`);
|
|
2411
|
-
if (await pageController.evaluate(`
|
|
1878
|
+
`);return await e.evaluate(`
|
|
2412
1879
|
!!(requestAnimationFrame.toString().includes('[native]') &&
|
|
2413
1880
|
(window.__canvasEngineHint || document.querySelector('[data-engine]')))
|
|
2414
|
-
`)
|
|
2415
|
-
engine: "Unknown Canvas Engine",
|
|
2416
|
-
confidence: .3,
|
|
2417
|
-
evidence: ["requestAnimationFrame hook detected", "canvas elements found"],
|
|
2418
|
-
adapterId: "none"
|
|
2419
|
-
});
|
|
2420
|
-
return {
|
|
2421
|
-
candidates,
|
|
2422
|
-
canvasCount: canvasInfo.length,
|
|
2423
|
-
canvasDetails: canvasId !== void 0 ? canvasInfo.filter((c) => c.id === canvasId || canvasInfo.indexOf(c).toString() === canvasId) : canvasInfo,
|
|
2424
|
-
fingerprintComplete: candidates.length > 0
|
|
2425
|
-
};
|
|
2426
|
-
}
|
|
2427
|
-
//#endregion
|
|
2428
|
-
//#region src/server/domains/canvas/handlers/scene-dump.ts
|
|
2429
|
-
async function handleSceneDump(pageController, args) {
|
|
2430
|
-
const canvasId = args["canvasId"];
|
|
2431
|
-
const opts = {
|
|
2432
|
-
canvasId,
|
|
2433
|
-
maxDepth: args["maxDepth"] ?? 20,
|
|
2434
|
-
onlyInteractive: args["onlyInteractive"] ?? false,
|
|
2435
|
-
onlyVisible: args["onlyVisible"] ?? false
|
|
2436
|
-
};
|
|
2437
|
-
const detection = await fingerprintCanvas(pageController, canvasId);
|
|
2438
|
-
if (!detection) return partialSceneDump(pageController, canvasId);
|
|
2439
|
-
const adapter = resolveAdapter(detection);
|
|
2440
|
-
if (!adapter) return partialSceneDump(pageController, canvasId);
|
|
2441
|
-
return adapter.dumpScene(buildEnv(pageController), opts);
|
|
2442
|
-
}
|
|
2443
|
-
async function partialSceneDump(pageController, canvasId) {
|
|
2444
|
-
const canvases = await pageController.evaluate(`
|
|
1881
|
+
`)&&i.length===0&&i.push({engine:`Unknown Canvas Engine`,confidence:.3,evidence:[`requestAnimationFrame hook detected`,`canvas elements found`],adapterId:`none`}),{candidates:i,canvasCount:a.length,canvasDetails:n===void 0?a:a.filter(e=>e.id===n||a.indexOf(e).toString()===n),fingerprintComplete:i.length>0}}async function x(e,t){let n=t.canvasId,r={canvasId:n,maxDepth:t.maxDepth??20,onlyInteractive:t.onlyInteractive??!1,onlyVisible:t.onlyVisible??!1},i=await y(e,n);if(!i)return S(e,n);let a=_(i);return a?a.dumpScene(v(e),r):S(e,n)}async function S(e,t){let n=await e.evaluate(`
|
|
2445
1882
|
(function() {
|
|
2446
1883
|
return Array.from(document.querySelectorAll('canvas')).map(function(c, i) {
|
|
2447
1884
|
var ctx2d = c.getContext('2d');
|
|
@@ -2455,41 +1892,12 @@ async function partialSceneDump(pageController, canvasId) {
|
|
|
2455
1892
|
};
|
|
2456
1893
|
});
|
|
2457
1894
|
})()
|
|
2458
|
-
`);
|
|
2459
|
-
return {
|
|
2460
|
-
engine: "unknown",
|
|
2461
|
-
version: void 0,
|
|
2462
|
-
canvas: (canvasId ? canvases.filter((c) => c.id === canvasId || canvases.indexOf(c).toString() === canvasId) : canvases)[0] ?? {
|
|
2463
|
-
id: canvasId ?? "",
|
|
2464
|
-
width: 0,
|
|
2465
|
-
height: 0,
|
|
2466
|
-
dpr: 1,
|
|
2467
|
-
contextType: "unknown"
|
|
2468
|
-
},
|
|
2469
|
-
sceneTree: null,
|
|
2470
|
-
totalNodes: 0,
|
|
2471
|
-
completeness: "partial",
|
|
2472
|
-
partialReason: "No canvas engine detected — only DOM canvas metadata returned"
|
|
2473
|
-
};
|
|
2474
|
-
}
|
|
2475
|
-
//#endregion
|
|
2476
|
-
//#region src/server/domains/canvas/handlers/pick.ts
|
|
2477
|
-
async function handlePick(pageController, args) {
|
|
2478
|
-
const x = args["x"];
|
|
2479
|
-
const y = args["y"];
|
|
2480
|
-
const canvasId = args["canvasId"];
|
|
2481
|
-
const highlight = args["highlight"] ?? false;
|
|
2482
|
-
const opts = {
|
|
2483
|
-
x,
|
|
2484
|
-
y,
|
|
2485
|
-
canvasId
|
|
2486
|
-
};
|
|
2487
|
-
const coordInfo = await pageController.evaluate(`
|
|
1895
|
+
`);return{engine:`unknown`,version:void 0,canvas:(t?n.filter(e=>e.id===t||n.indexOf(e).toString()===t):n)[0]??{id:t??``,width:0,height:0,dpr:1,contextType:`unknown`},sceneTree:null,totalNodes:0,completeness:`partial`,partialReason:`No canvas engine detected — only DOM canvas metadata returned`}}async function C(e,t){let n=t.x,r=t.y,i=t.canvasId,a=t.highlight??!1,o={x:n,y:r,canvasId:i},s=await e.evaluate(`
|
|
2488
1896
|
(function() {
|
|
2489
|
-
var sx = ${
|
|
1897
|
+
var sx = ${n}, sy = ${r};
|
|
2490
1898
|
var canvases = Array.from(document.querySelectorAll('canvas'));
|
|
2491
1899
|
var target = null;
|
|
2492
|
-
${
|
|
1900
|
+
${i?`target = document.getElementById(${JSON.stringify(i)}) || canvases[parseInt(${JSON.stringify(i)})];`:`
|
|
2493
1901
|
for (var i = canvases.length - 1; i >= 0; i--) {
|
|
2494
1902
|
var r = canvases[i].getBoundingClientRect();
|
|
2495
1903
|
if (sx >= r.left && sx <= r.right && sy >= r.top && sy <= r.bottom) {
|
|
@@ -2508,148 +1916,31 @@ async function handlePick(pageController, args) {
|
|
|
2508
1916
|
canvasY: (sy - rect.top) * (target.height / rect.height)
|
|
2509
1917
|
};
|
|
2510
1918
|
})()
|
|
2511
|
-
`);
|
|
2512
|
-
const detection = await fingerprintCanvas(pageController, canvasId);
|
|
2513
|
-
if (!detection) return {
|
|
2514
|
-
success: false,
|
|
2515
|
-
picked: null,
|
|
2516
|
-
candidates: [],
|
|
2517
|
-
coordinates: {
|
|
2518
|
-
screen: coordInfo.screen,
|
|
2519
|
-
canvas: {
|
|
2520
|
-
x: coordInfo.canvasX,
|
|
2521
|
-
y: coordInfo.canvasY
|
|
2522
|
-
}
|
|
2523
|
-
},
|
|
2524
|
-
hitTestMethod: "none"
|
|
2525
|
-
};
|
|
2526
|
-
const adapter = resolveAdapter(detection);
|
|
2527
|
-
if (!adapter) return {
|
|
2528
|
-
success: false,
|
|
2529
|
-
picked: null,
|
|
2530
|
-
candidates: [],
|
|
2531
|
-
coordinates: {
|
|
2532
|
-
screen: coordInfo.screen,
|
|
2533
|
-
canvas: {
|
|
2534
|
-
x: coordInfo.canvasX,
|
|
2535
|
-
y: coordInfo.canvasY
|
|
2536
|
-
}
|
|
2537
|
-
},
|
|
2538
|
-
hitTestMethod: "none"
|
|
2539
|
-
};
|
|
2540
|
-
const result = await adapter.pickAt(buildEnv(pageController), opts);
|
|
2541
|
-
if (highlight && result.picked) await highlightNode(pageController, result.picked.worldBounds).catch(() => {});
|
|
2542
|
-
return result;
|
|
2543
|
-
}
|
|
2544
|
-
async function highlightNode(pageController, bounds) {
|
|
2545
|
-
await pageController.evaluate(`
|
|
1919
|
+
`),c=await y(e,i);if(!c)return{success:!1,picked:null,candidates:[],coordinates:{screen:s.screen,canvas:{x:s.canvasX,y:s.canvasY}},hitTestMethod:`none`};let l=_(c);if(!l)return{success:!1,picked:null,candidates:[],coordinates:{screen:s.screen,canvas:{x:s.canvasX,y:s.canvasY}},hitTestMethod:`none`};let u=await l.pickAt(v(e),o);return a&&u.picked&&await w(e,u.picked.worldBounds).catch(()=>{}),u}async function w(e,t){await e.evaluate(`
|
|
2546
1920
|
(function() {
|
|
2547
1921
|
var existing = document.getElementById('__canvas-highlight');
|
|
2548
1922
|
if (existing) existing.remove();
|
|
2549
1923
|
var div = document.createElement('div');
|
|
2550
1924
|
div.id = '__canvas-highlight';
|
|
2551
1925
|
Object.assign(div.style, {
|
|
2552
|
-
position: 'fixed', left: ${
|
|
2553
|
-
width: ${
|
|
1926
|
+
position: 'fixed', left: ${t.x} + 'px', top: ${t.y} + 'px',
|
|
1927
|
+
width: ${t.width} + 'px', height: ${t.height} + 'px',
|
|
2554
1928
|
border: '2px solid #00ff88', pointerEvents: 'none', zIndex: 2147483647,
|
|
2555
1929
|
background: 'rgba(0,255,136,0.15)', boxSizing: 'border-box'
|
|
2556
1930
|
});
|
|
2557
1931
|
document.body.appendChild(div);
|
|
2558
1932
|
setTimeout(function() { div.remove(); }, 3000);
|
|
2559
1933
|
})()
|
|
2560
|
-
`);
|
|
2561
|
-
}
|
|
2562
|
-
//#endregion
|
|
2563
|
-
//#region src/server/domains/canvas/handlers/trace.ts
|
|
2564
|
-
async function handleTraceClick(pageController, debuggerManager, evidenceStore, args) {
|
|
2565
|
-
const x = args["x"];
|
|
2566
|
-
const y = args["y"];
|
|
2567
|
-
const canvasId = args["canvasId"];
|
|
2568
|
-
const maxFrames = args["maxFrames"] ?? 50;
|
|
2569
|
-
const breakpointType = args["breakpointType"] ?? "click";
|
|
2570
|
-
await debuggerManager.enable();
|
|
2571
|
-
await debuggerManager.ensureAdvancedFeatures();
|
|
2572
|
-
const eventMgr = debuggerManager.getEventManager();
|
|
2573
|
-
const breakpointId = await eventMgr.setEventListenerBreakpoint(breakpointType);
|
|
2574
|
-
let cleanupToken;
|
|
2575
|
-
let pendingDispatch;
|
|
2576
|
-
let primaryError;
|
|
2577
|
-
let cleanupError;
|
|
2578
|
-
let traceResult;
|
|
2579
|
-
try {
|
|
2580
|
-
const dispatch = await dispatchCanvasClick(pageController, x, y, canvasId, breakpointType);
|
|
2581
|
-
const dispatchResult = dispatch.result;
|
|
2582
|
-
pendingDispatch = dispatch.completion;
|
|
2583
|
-
cleanupToken = dispatchResult.cleanupToken;
|
|
2584
|
-
const pausedState = await debuggerManager.waitForPaused(5e3);
|
|
2585
|
-
let stackFrames = [];
|
|
2586
|
-
if (pausedState?.callFrames) stackFrames = pausedState.callFrames.slice(0, maxFrames).map((frame) => ({
|
|
2587
|
-
functionName: frame.functionName || "(anonymous)",
|
|
2588
|
-
scriptUrl: frame.url,
|
|
2589
|
-
lineNumber: frame.location?.lineNumber,
|
|
2590
|
-
columnNumber: frame.location?.columnNumber
|
|
2591
|
-
}));
|
|
2592
|
-
recordEvidence(evidenceStore, "canvas_trace", {
|
|
2593
|
-
engine: dispatchResult.engine ?? "unknown",
|
|
2594
|
-
x,
|
|
2595
|
-
y,
|
|
2596
|
-
handlerCount: stackFrames.length
|
|
2597
|
-
});
|
|
2598
|
-
traceResult = {
|
|
2599
|
-
inputFlow: dispatchResult.domEventChain ?? [],
|
|
2600
|
-
hitTarget: null,
|
|
2601
|
-
domEventChain: stackFrames.map((f) => ({
|
|
2602
|
-
type: breakpointType,
|
|
2603
|
-
target: f.scriptUrl,
|
|
2604
|
-
phase: "at-target"
|
|
2605
|
-
})),
|
|
2606
|
-
engineDispatchChain: dispatchResult.engineChain ?? [],
|
|
2607
|
-
handlerFrames: stackFrames,
|
|
2608
|
-
handlersTriggered: stackFrames.map((f) => ({
|
|
2609
|
-
functionName: f.functionName,
|
|
2610
|
-
scriptUrl: f.scriptUrl,
|
|
2611
|
-
lineNumber: f.lineNumber
|
|
2612
|
-
})),
|
|
2613
|
-
networkEmitted: []
|
|
2614
|
-
};
|
|
2615
|
-
} catch (error) {
|
|
2616
|
-
primaryError = error;
|
|
2617
|
-
} finally {
|
|
2618
|
-
try {
|
|
2619
|
-
await debuggerManager.resume();
|
|
2620
|
-
} catch {}
|
|
2621
|
-
if (pendingDispatch) try {
|
|
2622
|
-
await pendingDispatch;
|
|
2623
|
-
} catch (error) {
|
|
2624
|
-
if (!primaryError) cleanupError = error;
|
|
2625
|
-
}
|
|
2626
|
-
await cleanupCanvasTraceTarget(pageController, cleanupToken);
|
|
2627
|
-
if (typeof eventMgr.removeEventListenerBreakpoint === "function") try {
|
|
2628
|
-
await eventMgr.removeEventListenerBreakpoint(breakpointId);
|
|
2629
|
-
} catch {}
|
|
2630
|
-
}
|
|
2631
|
-
if (primaryError) throw primaryError;
|
|
2632
|
-
if (cleanupError) throw cleanupError;
|
|
2633
|
-
if (!traceResult) throw new Error("Canvas trace did not produce a result.");
|
|
2634
|
-
return traceResult;
|
|
2635
|
-
}
|
|
2636
|
-
async function dispatchCanvasClick(pageController, x, y, canvasId, breakpointType = "click") {
|
|
2637
|
-
if (breakpointType === "click" && typeof pageController.click === "function") return dispatchRealCanvasClick(pageController, x, y, canvasId, breakpointType);
|
|
2638
|
-
return dispatchSyntheticCanvasClick(pageController, x, y, canvasId, breakpointType);
|
|
2639
|
-
}
|
|
2640
|
-
async function dispatchRealCanvasClick(pageController, x, y, canvasId, breakpointType = "click") {
|
|
2641
|
-
const dispatchSequence = getDispatchSequence(breakpointType);
|
|
2642
|
-
const cleanupToken = `jshook-trace-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
|
|
2643
|
-
const prepared = await pageController.evaluate(`
|
|
1934
|
+
`)}async function T(e,t,n,r){let i=r.x,a=r.y,o=r.canvasId,s=r.maxFrames??50,c=r.breakpointType??`click`;await t.enable(),await t.ensureAdvancedFeatures();let l=t.getEventManager(),u=await l.setEventListenerBreakpoint(c),d,f,p,m,h;try{let r=await E(e,i,a,o,c),l=r.result;f=r.completion,d=l.cleanupToken;let u=await t.waitForPaused(5e3),p=[];u?.callFrames&&(p=u.callFrames.slice(0,s).map(e=>({functionName:e.functionName||`(anonymous)`,scriptUrl:e.url,lineNumber:e.location?.lineNumber,columnNumber:e.location?.columnNumber}))),j(n,`canvas_trace`,{engine:l.engine??`unknown`,x:i,y:a,handlerCount:p.length}),h={inputFlow:l.domEventChain??[],hitTarget:null,domEventChain:p.map(e=>({type:c,target:e.scriptUrl,phase:`at-target`})),engineDispatchChain:l.engineChain??[],handlerFrames:p,handlersTriggered:p.map(e=>({functionName:e.functionName,scriptUrl:e.scriptUrl,lineNumber:e.lineNumber})),networkEmitted:[]}}catch(e){p=e}finally{try{await t.resume()}catch{}if(f)try{await f}catch(e){p||(m=e)}if(await k(e,d),typeof l.removeEventListenerBreakpoint==`function`)try{await l.removeEventListenerBreakpoint(u)}catch{}}if(p)throw p;if(m)throw m;if(!h)throw Error(`Canvas trace did not produce a result.`);return h}async function E(e,t,n,r,i=`click`){return i===`click`&&typeof e.click==`function`?D(e,t,n,r,i):O(e,t,n,r,i)}async function D(e,t,n,r,i=`click`){let a=A(i),o=`jshook-trace-${Date.now()}-${Math.random().toString(36).slice(2,10)}`,s=await e.evaluate(`
|
|
2644
1935
|
(function() {
|
|
2645
|
-
var canvases = ${
|
|
1936
|
+
var canvases = ${r?`[document.getElementById(${JSON.stringify(r)})]`:`Array.from(document.querySelectorAll("canvas"))`};
|
|
2646
1937
|
var target = null;
|
|
2647
|
-
if (${!!
|
|
2648
|
-
target = document.getElementById(${JSON.stringify(
|
|
1938
|
+
if (${!!r}) {
|
|
1939
|
+
target = document.getElementById(${JSON.stringify(r)});
|
|
2649
1940
|
} else {
|
|
2650
1941
|
for (var i = canvases.length - 1; i >= 0; i--) {
|
|
2651
1942
|
var r = canvases[i].getBoundingClientRect();
|
|
2652
|
-
if (${
|
|
1943
|
+
if (${t} >= r.left && ${t} <= r.right && ${n} >= r.top && ${n} <= r.bottom) {
|
|
2653
1944
|
target = canvases[i];
|
|
2654
1945
|
break;
|
|
2655
1946
|
}
|
|
@@ -2657,46 +1948,30 @@ async function dispatchRealCanvasClick(pageController, x, y, canvasId, breakpoin
|
|
|
2657
1948
|
}
|
|
2658
1949
|
if (!target) return { domEventChain: [], pickedNode: null, engine: undefined, engineChain: [] };
|
|
2659
1950
|
|
|
2660
|
-
target.setAttribute('data-jshook-trace-token', ${JSON.stringify(
|
|
1951
|
+
target.setAttribute('data-jshook-trace-token', ${JSON.stringify(o)});
|
|
2661
1952
|
var rect = target.getBoundingClientRect();
|
|
2662
|
-
var offsetX = Math.max(0, Math.min(${
|
|
2663
|
-
var offsetY = Math.max(0, Math.min(${
|
|
1953
|
+
var offsetX = Math.max(0, Math.min(${t} - rect.left, Math.max(rect.width - 1, 0)));
|
|
1954
|
+
var offsetY = Math.max(0, Math.min(${n} - rect.top, Math.max(rect.height - 1, 0)));
|
|
2664
1955
|
return {
|
|
2665
|
-
domEventChain: ${JSON.stringify(
|
|
1956
|
+
domEventChain: ${JSON.stringify(a)},
|
|
2666
1957
|
pickedNode: target.id ? { id: String(target.id) } : null,
|
|
2667
1958
|
engine: window.Laya ? 'LayaAir' : (window.PIXI ? 'PixiJS' : undefined),
|
|
2668
1959
|
engineChain: [],
|
|
2669
|
-
cleanupToken: ${JSON.stringify(
|
|
2670
|
-
selector: 'canvas[data-jshook-trace-token="${
|
|
1960
|
+
cleanupToken: ${JSON.stringify(o)},
|
|
1961
|
+
selector: 'canvas[data-jshook-trace-token="${o}"]',
|
|
2671
1962
|
offset: { x: offsetX, y: offsetY }
|
|
2672
1963
|
};
|
|
2673
1964
|
})()
|
|
2674
|
-
`);
|
|
2675
|
-
if (!prepared.selector || !prepared.offset) return {
|
|
2676
|
-
result: prepared,
|
|
2677
|
-
completion: Promise.resolve()
|
|
2678
|
-
};
|
|
2679
|
-
return {
|
|
2680
|
-
result: prepared,
|
|
2681
|
-
completion: pageController.click?.(prepared.selector, {
|
|
2682
|
-
button: "left",
|
|
2683
|
-
clickCount: 1,
|
|
2684
|
-
offset: prepared.offset
|
|
2685
|
-
}) ?? Promise.resolve()
|
|
2686
|
-
};
|
|
2687
|
-
}
|
|
2688
|
-
async function dispatchSyntheticCanvasClick(pageController, x, y, canvasId, breakpointType = "click") {
|
|
2689
|
-
const dispatchSequence = getDispatchSequence(breakpointType);
|
|
2690
|
-
const script = `
|
|
1965
|
+
`);return!s.selector||!s.offset?{result:s,completion:Promise.resolve()}:{result:s,completion:e.click?.(s.selector,{button:`left`,clickCount:1,offset:s.offset})??Promise.resolve()}}async function O(e,t,n,r,i=`click`){let a=A(i),o=`
|
|
2691
1966
|
(function() {
|
|
2692
|
-
var canvases = ${
|
|
1967
|
+
var canvases = ${r?`[document.getElementById(${JSON.stringify(r)})]`:`Array.from(document.querySelectorAll("canvas"))`};
|
|
2693
1968
|
var target = null;
|
|
2694
|
-
if (${!!
|
|
2695
|
-
target = document.getElementById(${JSON.stringify(
|
|
1969
|
+
if (${!!r}) {
|
|
1970
|
+
target = document.getElementById(${JSON.stringify(r)});
|
|
2696
1971
|
} else {
|
|
2697
1972
|
for (var i = canvases.length - 1; i >= 0; i--) {
|
|
2698
1973
|
var r = canvases[i].getBoundingClientRect();
|
|
2699
|
-
if (${
|
|
1974
|
+
if (${t} >= r.left && ${t} <= r.right && ${n} >= r.top && ${n} <= r.bottom) {
|
|
2700
1975
|
target = canvases[i];
|
|
2701
1976
|
break;
|
|
2702
1977
|
}
|
|
@@ -2705,11 +1980,11 @@ async function dispatchSyntheticCanvasClick(pageController, x, y, canvasId, brea
|
|
|
2705
1980
|
if (!target) return { domEventChain: [], pickedNode: null, engine: undefined, engineChain: [] };
|
|
2706
1981
|
|
|
2707
1982
|
var rect = target.getBoundingClientRect();
|
|
2708
|
-
var cx = (${
|
|
2709
|
-
var cy = (${
|
|
1983
|
+
var cx = (${t} - rect.left) * (target.width / rect.width);
|
|
1984
|
+
var cy = (${n} - rect.top) * (target.height / rect.height);
|
|
2710
1985
|
|
|
2711
1986
|
var events = [];
|
|
2712
|
-
${JSON.stringify(
|
|
1987
|
+
${JSON.stringify(a)}.forEach(function(type) {
|
|
2713
1988
|
var EventCtor = type.indexOf('pointer') === 0 && typeof PointerEvent === 'function'
|
|
2714
1989
|
? PointerEvent
|
|
2715
1990
|
: MouseEvent;
|
|
@@ -2717,8 +1992,8 @@ async function dispatchSyntheticCanvasClick(pageController, x, y, canvasId, brea
|
|
|
2717
1992
|
view: window,
|
|
2718
1993
|
bubbles: true,
|
|
2719
1994
|
cancelable: true,
|
|
2720
|
-
clientX: ${
|
|
2721
|
-
clientY: ${
|
|
1995
|
+
clientX: ${t},
|
|
1996
|
+
clientY: ${n},
|
|
2722
1997
|
button: 0,
|
|
2723
1998
|
buttons: 1,
|
|
2724
1999
|
pointerId: 1
|
|
@@ -2733,73 +2008,12 @@ async function dispatchSyntheticCanvasClick(pageController, x, y, canvasId, brea
|
|
|
2733
2008
|
engineChain: []
|
|
2734
2009
|
};
|
|
2735
2010
|
})()
|
|
2736
|
-
`;
|
|
2737
|
-
return {
|
|
2738
|
-
result: await pageController.evaluate(script),
|
|
2739
|
-
completion: Promise.resolve()
|
|
2740
|
-
};
|
|
2741
|
-
}
|
|
2742
|
-
async function cleanupCanvasTraceTarget(pageController, cleanupToken) {
|
|
2743
|
-
if (!cleanupToken) return;
|
|
2744
|
-
try {
|
|
2745
|
-
await pageController.evaluate(`
|
|
2011
|
+
`;return{result:await e.evaluate(o),completion:Promise.resolve()}}async function k(e,t){if(t)try{await e.evaluate(`
|
|
2746
2012
|
(function() {
|
|
2747
|
-
var target = document.querySelector('canvas[data-jshook-trace-token="${
|
|
2013
|
+
var target = document.querySelector('canvas[data-jshook-trace-token="${t}"]');
|
|
2748
2014
|
if (target) {
|
|
2749
2015
|
target.removeAttribute('data-jshook-trace-token');
|
|
2750
2016
|
}
|
|
2751
2017
|
return true;
|
|
2752
2018
|
})()
|
|
2753
|
-
`);
|
|
2754
|
-
} catch {}
|
|
2755
|
-
}
|
|
2756
|
-
function getDispatchSequence(breakpointType) {
|
|
2757
|
-
if (breakpointType === "mousedown") return ["pointerdown", "mousedown"];
|
|
2758
|
-
if (breakpointType === "pointerdown") return ["pointerdown"];
|
|
2759
|
-
return [
|
|
2760
|
-
"pointerdown",
|
|
2761
|
-
"mousedown",
|
|
2762
|
-
"pointerup",
|
|
2763
|
-
"mouseup",
|
|
2764
|
-
"click"
|
|
2765
|
-
];
|
|
2766
|
-
}
|
|
2767
|
-
function recordEvidence(evidenceStore, label, metadata) {
|
|
2768
|
-
try {
|
|
2769
|
-
return evidenceStore.addNode("function", label, metadata).id;
|
|
2770
|
-
} catch {
|
|
2771
|
-
return "evidence-unavailable";
|
|
2772
|
-
}
|
|
2773
|
-
}
|
|
2774
|
-
//#endregion
|
|
2775
|
-
//#region src/server/domains/canvas/handlers.impl.ts
|
|
2776
|
-
var CanvasToolHandlers = class {
|
|
2777
|
-
pageController;
|
|
2778
|
-
debuggerManager;
|
|
2779
|
-
evidenceStore;
|
|
2780
|
-
constructor(deps) {
|
|
2781
|
-
this.pageController = deps.pageController;
|
|
2782
|
-
this.debuggerManager = deps.debuggerManager;
|
|
2783
|
-
this.evidenceStore = deps.evidenceStore;
|
|
2784
|
-
}
|
|
2785
|
-
async handleFingerprint(args) {
|
|
2786
|
-
return asJsonResponse(await handleFingerprint(this.pageController, args));
|
|
2787
|
-
}
|
|
2788
|
-
async handleSceneDump(args) {
|
|
2789
|
-
return asJsonResponse(await handleSceneDump(this.pageController, args));
|
|
2790
|
-
}
|
|
2791
|
-
async handlePick(args) {
|
|
2792
|
-
const x = argNumber(args, "x", 0);
|
|
2793
|
-
const y = argNumber(args, "y", 0);
|
|
2794
|
-
return asJsonResponse(await handlePick(this.pageController, {
|
|
2795
|
-
...args,
|
|
2796
|
-
x,
|
|
2797
|
-
y
|
|
2798
|
-
}));
|
|
2799
|
-
}
|
|
2800
|
-
async handleTraceClick(args) {
|
|
2801
|
-
return asJsonResponse(await handleTraceClick(this.pageController, this.debuggerManager, this.evidenceStore, args));
|
|
2802
|
-
}
|
|
2803
|
-
};
|
|
2804
|
-
//#endregion
|
|
2805
|
-
export { CanvasToolHandlers };
|
|
2019
|
+
`)}catch{}}function A(e){return e===`mousedown`?[`pointerdown`,`mousedown`]:e===`pointerdown`?[`pointerdown`]:[`pointerdown`,`mousedown`,`pointerup`,`mouseup`,`click`]}function j(e,t,n){try{return e.addNode(`function`,t,n).id}catch{return`evidence-unavailable`}}var M=class{pageController;debuggerManager;evidenceStore;constructor(e){this.pageController=e.pageController,this.debuggerManager=e.debuggerManager,this.evidenceStore=e.evidenceStore}async handleFingerprint(t){return e(await b(this.pageController,t))}async handleSceneDump(t){return e(await x(this.pageController,t))}async handlePick(n){let r=t(n,`x`,0),i=t(n,`y`,0);return e(await C(this.pageController,{...n,x:r,y:i}))}async handleTraceClick(t){return e(await T(this.pageController,this.debuggerManager,this.evidenceStore,t))}};export{M as CanvasToolHandlers};
|