@@ -13,15 +13,24 @@ import {
13
13
ThreadEvent ,
14
14
Variable ,
15
15
} from '@vscode/debugadapter' ;
16
- import { commands , FileSystemWatcher , QuickPickItem , QuickPickOptions , workspace , window } from 'vscode' ;
16
+ import {
17
+ commands ,
18
+ FileSystemWatcher ,
19
+ InputBoxOptions ,
20
+ QuickPickItem ,
21
+ QuickPickOptions ,
22
+ workspace ,
23
+ window ,
24
+ } from 'vscode' ;
17
25
import { DebugProtocol } from '@vscode/debugprotocol' ;
26
+ import { EventEmitter } from 'events' ;
18
27
import { LogOutputEvent , LogLevel } from '@vscode/debugadapter/lib/logger' ;
19
28
import { MessageStreamParser } from './MessageStreamParser' ;
20
29
import { SourceMaps } from './SourceMaps' ;
30
+ import { StatMessageModel , StatsProvider2 } from './StatsProvider2' ;
21
31
import * as path from 'path' ;
22
32
import * as fs from 'fs' ;
23
33
import { isUUID } from './Utils' ;
24
- import { StatMessageModel , StatsProvider2 } from './StatsProvider2' ;
25
34
26
35
interface PendingResponse {
27
36
onSuccess ?: Function ;
@@ -42,6 +51,7 @@ interface ProtocolCapabilities {
42
51
type : string ;
43
52
version : number ;
44
53
plugins : PluginDetails [ ] ;
54
+ require_passcode ?: boolean ;
45
55
}
46
56
47
57
// Interface for specific launch arguments.
@@ -58,6 +68,7 @@ interface IAttachRequestArguments extends DebugProtocol.AttachRequestArguments {
58
68
moduleMapping ?: ModuleMapping ;
59
69
sourceMapBias ?: string ;
60
70
targetModuleUuid ?: string ;
71
+ passcode ?: string ;
61
72
}
62
73
63
74
class TargetPluginItem implements QuickPickItem {
@@ -76,16 +87,18 @@ class TargetPluginItem implements QuickPickItem {
76
87
// 1 - initial version
77
88
// 2 - add targetModuleUuid to protocol event
78
89
// 3 - add array of plugins and target module ids to incoming protocol event
90
+ // 4 - mc can require a passcode to connect
79
91
enum ProtcolVersion {
80
92
Initial = 1 ,
81
93
SupportTargetModuleUuid = 2 ,
82
94
SupportTargetSelection = 3 ,
95
+ SupportPasscode = 4 ,
83
96
}
84
97
85
98
// The Debug Adapter for 'minecraft-js'
86
99
//
87
100
export class Session extends DebugSession {
88
- private static DEBUGGER_PROTOCOL_VERSION = ProtcolVersion . SupportTargetSelection ;
101
+ private static DEBUGGER_PROTOCOL_VERSION = ProtcolVersion . SupportPasscode ;
89
102
90
103
private static CONNECTION_RETRY_ATTEMPTS = 5 ;
91
104
private static CONNECTION_RETRY_WAIT_MS = 2000 ;
@@ -105,12 +118,27 @@ export class Session extends DebugSession {
105
118
private _moduleMapping ?: ModuleMapping ;
106
119
private _sourceMapBias ?: string ;
107
120
private _targetModuleUuid ?: string ;
121
+ private _passcode ?: string ;
122
+ private _statsProvider : StatsProvider2 ;
123
+ private _eventEmitter : any ;
108
124
109
- public constructor ( private _statsProvider2 : StatsProvider2 ) {
125
+ public constructor ( statsProvider : StatsProvider2 , eventEmitter : EventEmitter ) {
110
126
super ( ) ;
111
127
128
+ this . _statsProvider = statsProvider ;
129
+ this . _eventEmitter = eventEmitter ;
130
+
112
131
this . setDebuggerLinesStartAt1 ( true ) ;
113
132
this . setDebuggerColumnsStartAt1 ( true ) ;
133
+
134
+ // listen for events from the HomeViewProvider
135
+ this . _eventEmitter . on ( 'run-minecraft-command' , ( command : string ) => {
136
+ this . sendDebuggeeMessage ( {
137
+ type : 'minecraftCommand' ,
138
+ command : command ,
139
+ dimension_type : 'overworld' , // todo: get this from the user
140
+ } ) ;
141
+ } ) ;
114
142
}
115
143
116
144
// ------------------------------------------------------------------------
@@ -169,6 +197,7 @@ export class Session extends DebugSession {
169
197
if ( args . targetModuleUuid && isUUID ( args . targetModuleUuid ) ) {
170
198
this . _targetModuleUuid = args . targetModuleUuid . toLowerCase ( ) ;
171
199
}
200
+ this . _passcode = args . passcode ;
172
201
173
202
this . _localRoot = args . localRoot ? path . normalize ( args . localRoot ) : '' ;
174
203
this . _sourceMapRoot = args . sourceMapRoot ? path . normalize ( args . sourceMapRoot ) : undefined ;
@@ -505,14 +534,15 @@ export class Session extends DebugSession {
505
534
//
506
535
}
507
536
508
- private onConnectionComplete ( targetModuleUuid ?: string ) {
537
+ private onConnectionComplete ( targetModuleUuid ?: string , passcode ?: string ) {
509
538
this . _targetModuleUuid = targetModuleUuid ;
510
539
511
540
// respond with protocol version and chosen debugee target
512
541
this . sendDebuggeeMessage ( {
513
542
type : 'protocol' ,
514
543
version : Session . DEBUGGER_PROTOCOL_VERSION ,
515
544
target_module_uuid : targetModuleUuid ,
545
+ passcode : passcode ,
516
546
} ) ;
517
547
518
548
// show notifications for source map issues
@@ -665,7 +695,7 @@ export class Session extends DebugSession {
665
695
} else if ( eventMessage . type === 'ProtocolEvent' ) {
666
696
this . handleProtocolEvent ( eventMessage as ProtocolCapabilities ) ;
667
697
} else if ( eventMessage . type === 'StatEvent2' ) {
668
- this . _statsProvider2 . setStats ( eventMessage as StatMessageModel ) ;
698
+ this . _statsProvider . setStats ( eventMessage as StatMessageModel ) ;
669
699
}
670
700
}
671
701
@@ -730,7 +760,7 @@ export class Session extends DebugSession {
730
760
// ------------------------------------------------------------------------
731
761
732
762
// the final client event before connection is complete
733
- private handleProtocolEvent ( protocolCapabilities : ProtocolCapabilities ) {
763
+ private async handleProtocolEvent ( protocolCapabilities : ProtocolCapabilities ) : Promise < void > {
734
764
//
735
765
// handle protocol capabilities here...
736
766
// can fail connection on errors
@@ -739,17 +769,24 @@ export class Session extends DebugSession {
739
769
this . terminateSession ( 'protocol mismatch. Update Debugger Extension.' , LogLevel . Error ) ;
740
770
} else {
741
771
if ( protocolCapabilities . version == ProtcolVersion . SupportTargetModuleUuid ) {
742
- this . onConnectionComplete ( this . _targetModuleUuid ) ;
743
- } else if ( protocolCapabilities . version == ProtcolVersion . SupportTargetSelection ) {
772
+ this . onConnectionComplete ( this . _targetModuleUuid , undefined ) ;
773
+ } else if ( protocolCapabilities . version >= ProtcolVersion . SupportTargetSelection ) {
774
+ // no add-ons found, nothing to do
744
775
if ( ! protocolCapabilities . plugins || protocolCapabilities . plugins . length === 0 ) {
745
776
this . terminateSession ( 'protocol error. No Minecraft Add-Ons found.' , LogLevel . Error ) ;
746
777
return ;
747
- } else if ( this . _targetModuleUuid ) {
778
+ }
779
+
780
+ // if passcode is required, prompt user for it
781
+ let passcode = await this . promptForPasscode ( protocolCapabilities . require_passcode ) ;
782
+
783
+ // if a targetuuid was provided, make sure it's valid
784
+ if ( this . _targetModuleUuid ) {
748
785
const isValidTarget = protocolCapabilities . plugins . some (
749
786
plugin => plugin . module_uuid === this . _targetModuleUuid
750
787
) ;
751
788
if ( isValidTarget ) {
752
- this . onConnectionComplete ( this . _targetModuleUuid ) ;
789
+ this . onConnectionComplete ( this . _targetModuleUuid , passcode ) ;
753
790
return ;
754
791
} else {
755
792
this . showNotification (
@@ -758,7 +795,7 @@ export class Session extends DebugSession {
758
795
) ;
759
796
}
760
797
} else if ( protocolCapabilities . plugins . length === 1 ) {
761
- this . onConnectionComplete ( protocolCapabilities . plugins [ 0 ] . module_uuid ) ;
798
+ this . onConnectionComplete ( protocolCapabilities . plugins [ 0 ] . module_uuid , passcode ) ;
762
799
return ;
763
800
} else {
764
801
this . showNotification (
@@ -767,32 +804,50 @@ export class Session extends DebugSession {
767
804
) ;
768
805
}
769
806
770
- //
771
807
// Could not connect automatically, prompt user to select target.
772
- //
773
- const items : TargetPluginItem [ ] = protocolCapabilities . plugins . map (
774
- plugin => new TargetPluginItem ( plugin )
775
- ) ;
776
- const options : QuickPickOptions = {
777
- title : 'Choose the Minecraft Add-On to debug' ,
778
- ignoreFocusOut : true ,
779
- } ;
780
- window . showQuickPick ( items , options ) . then ( value => {
781
- if ( ! value ) {
782
- this . terminateSession (
783
- 'could not determine target Minecraft Add-On. You must specify the targetModuleUuid.' ,
784
- LogLevel . Error
785
- ) ;
786
- } else {
787
- this . onConnectionComplete ( value ?. targetModuleId ) ;
788
- }
789
- } ) ;
808
+ const targetUuid = await this . promptForTargetPlugin ( protocolCapabilities . plugins ) ;
809
+ if ( ! targetUuid ) {
810
+ this . terminateSession (
811
+ 'could not determine target Minecraft Add-On. You must specify the targetModuleUuid.' ,
812
+ LogLevel . Error
813
+ ) ;
814
+ return ;
815
+ }
816
+ this . onConnectionComplete ( targetUuid , passcode ) ;
790
817
} else {
791
818
this . terminateSession ( 'protocol unsupported. Update Debugger Extension.' , LogLevel . Error ) ;
792
819
}
793
820
}
794
821
}
795
822
823
+ private async promptForPasscode ( requirePasscode ?: boolean ) : Promise < string | undefined > {
824
+ if ( requirePasscode ) {
825
+ if ( this . _passcode ) {
826
+ return this . _passcode ;
827
+ } else {
828
+ const options : InputBoxOptions = {
829
+ title : 'Enter Passcode' ,
830
+ ignoreFocusOut : true ,
831
+ } ;
832
+ return await window . showInputBox ( options ) ;
833
+ }
834
+ }
835
+ return undefined ;
836
+ }
837
+
838
+ private async promptForTargetPlugin ( plugins : PluginDetails [ ] ) : Promise < string | undefined > {
839
+ const items : TargetPluginItem [ ] = plugins . map ( plugin => new TargetPluginItem ( plugin ) ) ;
840
+ const options : QuickPickOptions = {
841
+ title : 'Choose the Minecraft Add-On to debug' ,
842
+ ignoreFocusOut : true ,
843
+ } ;
844
+ const targetItem = await window . showQuickPick ( items , options ) ;
845
+ if ( targetItem ) {
846
+ return targetItem . targetModuleId ;
847
+ }
848
+ return undefined ;
849
+ }
850
+
796
851
// check that source and map properties in launch.json are set correctly
797
852
private checkSourceFilePaths ( ) {
798
853
if ( this . _sourceMapRoot ) {
0 commit comments