Skip to content

Commit 1b6a6d1

Browse files
authored
feat(debugger): prompt user for target add-on id if not provided and multiple add-ons active in MC. (#185)
In an effort to improve the "it just works" scenarios, this PR presents a QuickPickMenu to the user if the targetModuleUUID is not set (or incorrect) and MC has multiple active add-ons. - if a targetModuleUUID is set and MC reports having this plugin, no pop up menu - if target is set and MC does not have this plugin, warn and then show pop with available plugins - if target is not set but there's only 1 active plugin, connect without menu - if target is not set and there are multiple active plugins, show pop up menu
1 parent f724ced commit 1b6a6d1

File tree

1 file changed

+105
-21
lines changed

1 file changed

+105
-21
lines changed

src/Session.ts

Lines changed: 105 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ import {
1313
ThreadEvent,
1414
Variable,
1515
} from '@vscode/debugadapter';
16+
import { commands, FileSystemWatcher, QuickPickItem, QuickPickOptions, workspace, window } from 'vscode';
1617
import { DebugProtocol } from '@vscode/debugprotocol';
1718
import { LogOutputEvent, LogLevel } from '@vscode/debugadapter/lib/logger';
1819
import { MessageStreamParser } from './MessageStreamParser';
1920
import { SourceMaps } from './SourceMaps';
20-
import { FileSystemWatcher, window, workspace, commands } from 'vscode';
2121
import * as path from 'path';
2222
import * as fs from 'fs';
2323
import { isUUID } from './Utils';
@@ -33,6 +33,17 @@ interface ModuleMapping {
3333
[moduleName: string]: string;
3434
}
3535

36+
interface PluginDetails {
37+
name: string;
38+
module_uuid: string;
39+
}
40+
41+
interface ProtocolCapabilities {
42+
type: string;
43+
version: number;
44+
plugins: PluginDetails[];
45+
}
46+
3647
// Interface for specific launch arguments.
3748
// See package.json for schema.
3849
interface IAttachRequestArguments extends DebugProtocol.AttachRequestArguments {
@@ -49,10 +60,33 @@ interface IAttachRequestArguments extends DebugProtocol.AttachRequestArguments {
4960
targetModuleUuid?: string;
5061
}
5162

63+
class TargetPluginItem implements QuickPickItem {
64+
public label: string;
65+
public detail: string;
66+
public targetModuleId: string;
67+
68+
constructor(pluginDetails: PluginDetails) {
69+
this.label = pluginDetails.name;
70+
this.detail = 'Script module uuid ' + pluginDetails.module_uuid;
71+
this.targetModuleId = pluginDetails.module_uuid;
72+
}
73+
}
74+
75+
// protocol version history
76+
// 1 - initial version
77+
// 2 - add targetModuleUuid to protocol event
78+
// 3 - add array of plugins and target module ids to incoming protocol event
79+
enum ProtcolVersion {
80+
Initial = 1,
81+
SupportTargetModuleUuid = 2,
82+
SupportTargetSelection = 3,
83+
}
84+
5285
// The Debug Adapter for 'minecraft-js'
5386
//
5487
export class Session extends DebugSession {
55-
private static DEBUGGER_PROTOCOL_VERSION = 2;
88+
private static DEBUGGER_PROTOCOL_VERSION = ProtcolVersion.SupportTargetSelection;
89+
5690
private static CONNECTION_RETRY_ATTEMPTS = 5;
5791
private static CONNECTION_RETRY_WAIT_MS = 2000;
5892

@@ -132,13 +166,7 @@ export class Session extends DebugSession {
132166
this.sendErrorResponse(response, 1001, `Failed to attach to Minecraft, invalid port "${args.inputPort}".`);
133167
return;
134168
}
135-
136-
if (!args.targetModuleUuid || args.targetModuleUuid === '' || !isUUID(args.targetModuleUuid)) {
137-
this.showNotification(
138-
'Launch config module target (targetModuleUuid) is not a valid uuid. This should be set to the script module uuid from your manifest.json. Omitting this may cause problems when multiple Minecraft Add-Ons are active.',
139-
LogLevel.Warn
140-
);
141-
} else {
169+
if (args.targetModuleUuid && isUUID(args.targetModuleUuid)) {
142170
this._targetModuleUuid = args.targetModuleUuid.toLowerCase();
143171
}
144172

@@ -477,7 +505,19 @@ export class Session extends DebugSession {
477505
//
478506
}
479507

480-
private onConnectionComplete() {
508+
private onConnectionComplete(targetModuleUuid?: string) {
509+
this._targetModuleUuid = targetModuleUuid;
510+
511+
// respond with protocol version and chosen debugee target
512+
this.sendDebuggeeMessage({
513+
type: 'protocol',
514+
version: Session.DEBUGGER_PROTOCOL_VERSION,
515+
target_module_uuid: targetModuleUuid,
516+
});
517+
518+
// show notifications for source map issues
519+
this.checkSourceFilePaths();
520+
481521
// success
482522
this.showNotification('Success! Debugger is now connected.', LogLevel.Log);
483523

@@ -620,8 +660,10 @@ export class Session extends DebugSession {
620660
this.sendEvent(new ThreadEvent(eventMessage.reason, eventMessage.thread));
621661
} else if (eventMessage.type === 'PrintEvent') {
622662
this.handlePrintEvent(eventMessage.message, eventMessage.logLevel);
663+
} else if (eventMessage.type === 'NotificationEvent') {
664+
this.showNotification(eventMessage.message, eventMessage.logLevel);
623665
} else if (eventMessage.type === 'ProtocolEvent') {
624-
this.handleProtocolEvent(eventMessage);
666+
this.handleProtocolEvent(eventMessage as ProtocolCapabilities);
625667
} else if (eventMessage.type === 'StatEvent2') {
626668
this._statsProvider2.setStats(eventMessage as StatMessageModel);
627669
}
@@ -688,24 +730,66 @@ export class Session extends DebugSession {
688730
// ------------------------------------------------------------------------
689731

690732
// the final client event before connection is complete
691-
private handleProtocolEvent(protocolCapabilities: any) {
733+
private handleProtocolEvent(protocolCapabilities: ProtocolCapabilities) {
692734
//
693735
// handle protocol capabilities here...
694736
// can fail connection on errors
695737
//
696738
if (Session.DEBUGGER_PROTOCOL_VERSION < protocolCapabilities.version) {
697739
this.terminateSession('protocol mismatch. Update Debugger Extension.', LogLevel.Error);
698740
} else {
699-
this.sendDebuggeeMessage({
700-
type: 'protocol',
701-
version: Session.DEBUGGER_PROTOCOL_VERSION,
702-
target_module_uuid: this._targetModuleUuid,
703-
});
704-
705-
this.checkSourceFilePaths();
741+
if (protocolCapabilities.version == ProtcolVersion.SupportTargetModuleUuid) {
742+
this.onConnectionComplete(this._targetModuleUuid);
743+
} else if (protocolCapabilities.version == ProtcolVersion.SupportTargetSelection) {
744+
if (!protocolCapabilities.plugins || protocolCapabilities.plugins.length === 0) {
745+
this.terminateSession('protocol error. No Minecraft Add-Ons found.', LogLevel.Error);
746+
return;
747+
} else if (this._targetModuleUuid) {
748+
const isValidTarget = protocolCapabilities.plugins.some(
749+
plugin => plugin.module_uuid === this._targetModuleUuid
750+
);
751+
if (isValidTarget) {
752+
this.onConnectionComplete(this._targetModuleUuid);
753+
return;
754+
} else {
755+
this.showNotification(
756+
`Minecraft Add-On script module not found with targetModuleUuid ${this._targetModuleUuid} specified in launch.json. Prompting for debug target.`,
757+
LogLevel.Warn
758+
);
759+
}
760+
} else if (protocolCapabilities.plugins.length === 1) {
761+
this.onConnectionComplete(protocolCapabilities.plugins[0].module_uuid);
762+
return;
763+
} else {
764+
this.showNotification(
765+
'The targetModuleUuid in launch.json is not set to a valid uuid. Set this to a script module uuid (manifest.json) to avoid the selection prompt.',
766+
LogLevel.Warn
767+
);
768+
}
706769

707-
// success
708-
this.onConnectionComplete();
770+
//
771+
// 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+
});
790+
} else {
791+
this.terminateSession('protocol unsupported. Update Debugger Extension.', LogLevel.Error);
792+
}
709793
}
710794
}
711795

0 commit comments

Comments
 (0)