mirror of
https://github.com/godotengine/godot-csharp-vscode.git
synced 2025-12-31 21:48:32 +03:00
Fixed messaging with the Godot editor not working on Windows
This commit is contained in:
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@@ -12,7 +12,7 @@
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/dist/**/*.js"
|
||||
],
|
||||
"preLaunchTask": "npm: compile-tsc-debug"
|
||||
"preLaunchTask": "npm: webpack-debug"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -13,43 +13,41 @@ namespace GodotDebugSession
|
||||
private static readonly string LogPath = $"{ThisAppPathWithoutExtension}.log";
|
||||
internal static readonly string NewLogPath = $"{ThisAppPathWithoutExtension}.new.log";
|
||||
|
||||
private static StreamWriter NewWriter() => new StreamWriter(LogPath, append: true, Encoding.UTF8);
|
||||
private static StreamWriter _writer;
|
||||
|
||||
private static void Log(StreamWriter writer, string message)
|
||||
{
|
||||
writer.WriteLine($"{DateTime.Now:HH:mm:ss.ffffff}: {message}");
|
||||
}
|
||||
private static StreamWriter Writer =>
|
||||
_writer ?? (_writer = new StreamWriter(LogPath, append: true, Encoding.UTF8));
|
||||
|
||||
public static void Log(string message)
|
||||
private static void WriteLog(string message)
|
||||
{
|
||||
using (var writer = NewWriter())
|
||||
try
|
||||
{
|
||||
Log(writer, message);
|
||||
var writer = Writer;
|
||||
writer.WriteLine($"{DateTime.Now:HH:mm:ss.ffffff}: {message}");
|
||||
writer.Flush();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
Console.Error.WriteLine(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LogError(string message)
|
||||
{
|
||||
using (var writer = NewWriter())
|
||||
{
|
||||
Log(writer, message);
|
||||
}
|
||||
}
|
||||
public static void Log(string message) =>
|
||||
WriteLog(message);
|
||||
|
||||
public static void LogError(string message, Exception ex)
|
||||
{
|
||||
using (var writer = NewWriter())
|
||||
{
|
||||
Log(writer, $"{message}\n{ex}");
|
||||
}
|
||||
}
|
||||
public static void LogError(string message) =>
|
||||
WriteLog(message);
|
||||
|
||||
public static void LogError(Exception ex)
|
||||
public static void LogError(string message, Exception ex) =>
|
||||
WriteLog($"{message}\n{ex}");
|
||||
|
||||
public static void LogError(Exception ex) =>
|
||||
WriteLog(ex.ToString());
|
||||
|
||||
public static void Close()
|
||||
{
|
||||
using (var writer = NewWriter())
|
||||
{
|
||||
Log(writer, ex.ToString());
|
||||
}
|
||||
_writer?.Close();
|
||||
_writer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,10 @@ namespace GodotDebugSession
|
||||
{
|
||||
Logger.LogError(ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Logger.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
28
README.md
28
README.md
@@ -2,17 +2,35 @@
|
||||
|
||||
Debugger and utilities for working with Godot C# projects in VSCode.
|
||||
|
||||
## Requirements
|
||||
|
||||
**Godot 3.2.2** or greater. Older versions of Godot are not supported.
|
||||
|
||||
## Features
|
||||
|
||||
- Debugging.
|
||||
- Launch a game directly from the Godot editor.
|
||||
- Code completion for Node paths, Input actions, Resource paths, Scene paths and Signal names.
|
||||
- Launch a game directly in the Godot editor from VSCode.
|
||||
- Additional code completion for Node paths, Input actions, Resource paths, Scene paths and Signal names.
|
||||
|
||||
## Requirements
|
||||
**NOTES:**
|
||||
- A running Godot instance must be editing the project in order for `Play in Editor` and the code completion to work.
|
||||
- Node path suggestions are provided from the currently edited scene in the Godot editor.
|
||||
- Currently Signal suggestions are only provided using the information from the project build
|
||||
results, not from the information in the edited document. This will change in the future.
|
||||
|
||||
Godot 3.2.3 or 4.0 or greater is required (both versions are currently unreleaded).
|
||||
## Debugger launch configurations
|
||||
|
||||
A Godot editor instance must be running for the project in order for code completion to work.
|
||||
By default the extension creates the following launch configurations:
|
||||
|
||||
- **Play in Editor**\
|
||||
Launches the game in the Godot editor for debugging in VSCode.\
|
||||
For this option to work, a running Godot instance must be editing the project.
|
||||
- **Launch**\
|
||||
Launches the game with a Godot executable for debugging in VSCode.\
|
||||
Before using this option, the value of the _"executable"_ property must be changed
|
||||
to a path that points to the Godot executable that will be launched launched.
|
||||
- **Attach**\
|
||||
Attaches to a running Godot instance that was configured to listen for a debugger connection.
|
||||
|
||||
## Screenshots
|
||||
|
||||
|
||||
@@ -27,7 +27,10 @@
|
||||
"compile": "make build",
|
||||
"compile-tsc": "make tsc",
|
||||
"compile-tsc-debug": "make tsc-debug",
|
||||
"watch": "tsc -watch -p ./"
|
||||
"watch": "tsc -watch -p ./",
|
||||
"webpack": "webpack --mode production",
|
||||
"webpack-debug": "webpack --mode development",
|
||||
"webpack-watch": "webpack --mode development --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"chokidar": "^3.4.0",
|
||||
@@ -46,7 +49,7 @@
|
||||
"glob": "^7.1.4",
|
||||
"make": "^0.8.1",
|
||||
"mocha": "^6.1.4",
|
||||
"ts-loader": "^7.0.3",
|
||||
"ts-loader": "^7.0.5",
|
||||
"tslint": "^5.12.1",
|
||||
"typescript": "^3.3.1",
|
||||
"vsce": "^1.20.0",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as vscode from 'vscode';
|
||||
import { Client, MessageStatus } from './godot-tools-messaging/client';
|
||||
import { fixPathForGodot } from './godot-utils';
|
||||
|
||||
enum CompletionKind {
|
||||
InputActions = 0,
|
||||
@@ -49,7 +50,7 @@ export class GodotCompletionProvider implements vscode.CompletionItemProvider {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let filePath = document.uri.fsPath;
|
||||
let filePath = fixPathForGodot(document.uri.fsPath);
|
||||
|
||||
let [lines, character] = this.getPrefixLines(document, position);
|
||||
let linePrefix = lines.substr(0, character);
|
||||
|
||||
@@ -2,6 +2,7 @@ import * as vscode from 'vscode';
|
||||
import { DebugProtocol } from 'vscode-debugprotocol';
|
||||
import { Client, Peer, MessageContent, MessageStatus, ILogger, IMessageHandler } from './godot-tools-messaging/client';
|
||||
import * as completion_provider from './completion-provider';
|
||||
import { fixPathForGodot } from './godot-utils';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
|
||||
@@ -91,7 +92,13 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
let godotProjectFile = path.join(rootPath, 'project.godot');
|
||||
|
||||
return fs.existsSync(godotProjectFile);
|
||||
})!.uri.path;
|
||||
})?.uri.fsPath;
|
||||
|
||||
if (godotProjectDir === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
godotProjectDir = fixPathForGodot(godotProjectDir);
|
||||
|
||||
client = new Client('VisualStudioCode', godotProjectDir, new MessageHandler(), new Logger());
|
||||
client.start();
|
||||
@@ -129,7 +136,9 @@ class GodotMonoDebugConfigProvider implements vscode.DebugConfigurationProvider
|
||||
debugConfiguration.__exceptionOptions = convertToExceptionOptions(getModel());
|
||||
}
|
||||
|
||||
debugConfiguration['godotProjectDir'] = folder?.uri.fsPath;
|
||||
if (folder !== undefined) {
|
||||
debugConfiguration['godotProjectDir'] = folder.uri.fsPath;
|
||||
}
|
||||
|
||||
return debugConfiguration;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import * as path from 'path';
|
||||
import * as chokidar from 'chokidar';
|
||||
import PromiseSocket from 'promise-socket';
|
||||
import { Disposable } from 'vscode';
|
||||
import { throws } from 'assert';
|
||||
|
||||
async function timeout(ms: number) {
|
||||
return new Promise(resolve => {
|
||||
@@ -35,7 +34,8 @@ class CustomSocket extends PromiseSocket<net.Socket> {
|
||||
let indexOfLineBreak = this.buffer.indexOf('\n');
|
||||
|
||||
if (indexOfLineBreak >= 0) {
|
||||
let line = this.buffer.substring(0, indexOfLineBreak);
|
||||
let hasCR = indexOfLineBreak !== 0 && this.buffer.charAt(indexOfLineBreak - 1) === '\r';
|
||||
let line = this.buffer.substring(0, hasCR ? indexOfLineBreak - 1 : indexOfLineBreak);
|
||||
this.buffer = this.buffer.substring(indexOfLineBreak + 1);
|
||||
return line;
|
||||
}
|
||||
@@ -269,24 +269,46 @@ export class Client implements Disposable {
|
||||
return;
|
||||
}
|
||||
|
||||
const socket = new CustomSocket();
|
||||
const attempts = 3;
|
||||
let attemptsLeft = attempts;
|
||||
|
||||
this.logger.logInfo('Connecting to Godot Ide Server');
|
||||
while (attemptsLeft-- > 0) {
|
||||
if (attemptsLeft < (attempts - 1)) {
|
||||
this.logger.logInfo(`Waiting 3 seconds... (${attemptsLeft + 1} attempts left)`);
|
||||
await timeout(5000);
|
||||
}
|
||||
|
||||
await socket.connect(this.metadata!.port, 'localhost');
|
||||
const socket = new CustomSocket();
|
||||
|
||||
this.logger.logInfo('Connection open with Godot Ide Server');
|
||||
this.logger.logInfo('Connecting to Godot Ide Server');
|
||||
|
||||
this.peer = new Peer(socket, new ClientHandshake(), this.messageHandler, this.logger);
|
||||
try {
|
||||
await socket.connect(this.metadata!.port, 'localhost');
|
||||
}
|
||||
catch (err) {
|
||||
this.logger.logError('Failed to connect to Godot Ide Server', err);
|
||||
continue;
|
||||
}
|
||||
|
||||
this.logger.logInfo('Connection open with Godot Ide Server');
|
||||
|
||||
this.peer?.dispose();
|
||||
this.peer = new Peer(socket, new ClientHandshake(), this.messageHandler, this.logger);
|
||||
|
||||
if (!await this.peer.doHandshake(this.identity)) {
|
||||
this.logger.logError('Handshake failed');
|
||||
this.peer.dispose();
|
||||
continue;
|
||||
}
|
||||
|
||||
await this.peer.process();
|
||||
|
||||
this.logger.logInfo('Connection closed with Ide Client');
|
||||
|
||||
if (!await this.peer.doHandshake(this.identity)) {
|
||||
this.logger.logError('Handshake failed');
|
||||
return;
|
||||
}
|
||||
|
||||
await this.peer.process();
|
||||
|
||||
this.logger.logInfo('Connection closed with Ide Client');
|
||||
this.logger.logInfo(`Failed to connect to Godot Ide Server after ${attempts} attempts`);
|
||||
}
|
||||
|
||||
startWatching(): void {
|
||||
|
||||
15
src/godot-utils.ts
Normal file
15
src/godot-utils.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
export function fixPathForGodot(path: string): string {
|
||||
if (process.platform === "win32") {
|
||||
// Godot expects the drive letter to be upper case
|
||||
if (path && path.charAt(1) === ':') {
|
||||
let drive = path[0];
|
||||
let driveUpper = drive.toUpperCase();
|
||||
if (driveUpper !== drive) {
|
||||
path = driveUpper + path.substr(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
Reference in New Issue
Block a user