mirror of
https://github.com/godotengine/godot-csharp-vscode.git
synced 2025-12-31 21:48:32 +03:00
Re-implements launching the Godot process with MedallionShell and provides the executableArguments to the command. MedallionShell handles the escaping of the arguments.
133 lines
4.3 KiB
C#
133 lines
4.3 KiB
C#
using System;
|
|
using System.Net;
|
|
using Mono.Debugging.Client;
|
|
using Mono.Debugging.Soft;
|
|
using VSCodeDebug;
|
|
|
|
namespace GodotDebugSession
|
|
{
|
|
public class GodotDebugSession : MonoDebugSession, IProcessOutputListener
|
|
{
|
|
public GodotDebugSession() : base(new GodotDebuggerSession(), new CustomLogger())
|
|
{
|
|
}
|
|
|
|
public override void Launch(Response response, dynamic args)
|
|
{
|
|
ExecutionType executionType;
|
|
|
|
string godotExecutablePath = getString(args, "executable");
|
|
|
|
string mode = getString(args, "mode");
|
|
if (string.IsNullOrEmpty(mode) || (mode != "playInEditor" && mode != "executable"))
|
|
{
|
|
executionType = !string.IsNullOrEmpty(godotExecutablePath) ?
|
|
ExecutionType.Launch :
|
|
ExecutionType.PlayInEditor;
|
|
}
|
|
else
|
|
{
|
|
executionType = mode == "playInEditor" ? ExecutionType.PlayInEditor : ExecutionType.Launch;
|
|
}
|
|
|
|
RunImpl(response, args, executionType);
|
|
}
|
|
|
|
public override void Attach(Response response, dynamic args)
|
|
{
|
|
RunImpl(response, args, ExecutionType.Attach);
|
|
}
|
|
|
|
private void RunImpl(Response response, dynamic args, ExecutionType executionType)
|
|
{
|
|
lock (_lock)
|
|
{
|
|
_attachMode = executionType == ExecutionType.Attach;
|
|
|
|
SetExceptionBreakpoints(args.__exceptionOptions);
|
|
|
|
SoftDebuggerRemoteArgs listenArgs;
|
|
|
|
if (executionType == ExecutionType.Attach)
|
|
{
|
|
// validate argument 'address'
|
|
string host = getString(args, "address");
|
|
if (host == null)
|
|
{
|
|
SendErrorResponse(response, 3007, "Property 'address' is missing or empty.");
|
|
return;
|
|
}
|
|
|
|
// validate argument 'port'
|
|
int port = getInt(args, "port", -1);
|
|
if (port == -1)
|
|
{
|
|
SendErrorResponse(response, 3008, "Property 'port' is missing.");
|
|
return;
|
|
}
|
|
|
|
IPAddress address = Utilities.ResolveIPAddress(host);
|
|
if (address == null)
|
|
{
|
|
SendErrorResponse(response, 3013, "Invalid address '{host}'.", new { host });
|
|
return;
|
|
}
|
|
|
|
listenArgs = new SoftDebuggerConnectArgs("Godot", IPAddress.Loopback, port);
|
|
}
|
|
else
|
|
{
|
|
listenArgs = new SoftDebuggerListenArgs("Godot", IPAddress.Loopback, 0);
|
|
}
|
|
|
|
// ------
|
|
|
|
_debuggeeKilled = false;
|
|
|
|
string godotExecutablePath = (string)args.executable;
|
|
string[] executableArguments = args.executableArguments?.ToObject<string[]>() ?? Array.Empty<string>();
|
|
|
|
string godotProjectDir = (string)args.godotProjectDir;
|
|
|
|
var startInfo = new GodotDebuggerStartInfo(executionType,
|
|
godotExecutablePath, executableArguments, processOutputListener: this, listenArgs)
|
|
{ WorkingDirectory = godotProjectDir };
|
|
|
|
_session.Run(startInfo, _debuggerSessionOptions);
|
|
|
|
_debuggeeExecuting = true;
|
|
}
|
|
}
|
|
|
|
private class CustomLogger : ICustomLogger
|
|
{
|
|
public void LogError(string message, Exception ex) => Logger.LogError(message, ex);
|
|
|
|
public void LogAndShowException(string message, Exception ex) => LogError(message, ex);
|
|
|
|
public void LogMessage(string messageFormat, params object[] args)
|
|
{
|
|
Logger.Log(string.Format(messageFormat, args));
|
|
}
|
|
|
|
public string GetNewDebuggerLogFilename() => Logger.NewLogPath;
|
|
}
|
|
|
|
public void ReceiveStdOut(string data)
|
|
{
|
|
if (data == null)
|
|
_stdoutEOF = true;
|
|
|
|
SendOutput("stdout", data);
|
|
}
|
|
|
|
public void ReceiveStdErr(string data)
|
|
{
|
|
if (data == null)
|
|
_stdoutEOF = true;
|
|
|
|
SendOutput("stderr", data);
|
|
}
|
|
}
|
|
}
|