Skip to content

Commit

Permalink
Auto-Increment Debugger Port
Browse files Browse the repository at this point in the history
Note: This PR also changes the port of the GDScript Language Server from 6008 to 6005. This opens enough ports above the debug port (6007) for this change to be useful.
  • Loading branch information
nathanfranke committed Dec 4, 2021
1 parent 2a9dd65 commit de7873c
Show file tree
Hide file tree
Showing 10 changed files with 106 additions and 48 deletions.
5 changes: 5 additions & 0 deletions editor/debugger/editor_debugger_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,11 @@ ScriptEditorDebugger *EditorDebuggerNode::get_default_debugger() const {
return Object::cast_to<ScriptEditorDebugger>(tabs->get_tab_control(0));
}

String EditorDebuggerNode::get_server_uri() const {
ERR_FAIL_COND_V(server.is_null(), "");
return server->get_uri();
}

Error EditorDebuggerNode::start(const String &p_uri) {
stop();
ERR_FAIL_COND_V(p_uri.find("://") < 0, ERR_INVALID_PARAMETER);
Expand Down
3 changes: 2 additions & 1 deletion editor/debugger/editor_debugger_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,9 @@ class EditorDebuggerNode : public MarginContainer {
void set_camera_override(CameraOverride p_override);
CameraOverride get_camera_override();

Error start(const String &p_uri = "tcp://");
String get_server_uri() const;

Error start(const String &p_uri = "tcp://");
void stop();

void add_debugger_plugin(const Ref<Script> &p_script);
Expand Down
48 changes: 36 additions & 12 deletions editor/debugger/editor_debugger_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,18 @@
class EditorDebuggerServerTCP : public EditorDebuggerServer {
private:
Ref<TCPServer> server;
String endpoint;

public:
static EditorDebuggerServer *create(const String &p_protocol);
virtual void poll() {}
virtual Error start(const String &p_uri);
virtual void stop();
virtual bool is_active() const;
virtual bool is_connection_available() const;
virtual Ref<RemoteDebuggerPeer> take_connection();

virtual void poll() override {}
virtual String get_uri() const override;
virtual Error start(const String &p_uri) override;
virtual void stop() override;
virtual bool is_active() const override;
virtual bool is_connection_available() const override;
virtual Ref<RemoteDebuggerPeer> take_connection() override;

EditorDebuggerServerTCP();
};
Expand All @@ -63,21 +66,42 @@ EditorDebuggerServerTCP::EditorDebuggerServerTCP() {
server.instantiate();
}

String EditorDebuggerServerTCP::get_uri() const {
return endpoint;
}

Error EditorDebuggerServerTCP::start(const String &p_uri) {
int bind_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port");
// Default host and port
String bind_host = (String)EditorSettings::get_singleton()->get("network/debug/remote_host");
int bind_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port");

// Optionally override
if (!p_uri.is_empty() && p_uri != "tcp://") {
String scheme, path;
Error err = p_uri.parse_url(scheme, bind_host, bind_port, path);
ERR_FAIL_COND_V(err != OK, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(!bind_host.is_valid_ip_address() && bind_host != "*", ERR_INVALID_PARAMETER);
}
const Error err = server->listen(bind_port, bind_host);
if (err != OK) {
EditorNode::get_log()->add_message(String("Error listening on port ") + itos(bind_port), EditorLog::MSG_TYPE_ERROR);
return err;

// Try listening on ports
const int max_attempts = 5;
for (int attempt = 1;; ++attempt) {
const Error err = server->listen(bind_port, bind_host);
if (err == OK) {
break;
}
if (attempt >= max_attempts) {
EditorNode::get_log()->add_message(vformat("Cannot listen on port %d, remote debugging unavailable.", bind_port), EditorLog::MSG_TYPE_ERROR);
return err;
}
int last_port = bind_port++;
EditorNode::get_log()->add_message(vformat("Cannot listen on port %d, trying %d instead.", last_port, bind_port), EditorLog::MSG_TYPE_WARNING);
}
return err;

// Endpoint that the client should connect to
endpoint = vformat("tcp://%s:%d", bind_host, bind_port);

return OK;
}

void EditorDebuggerServerTCP::stop() {
Expand Down
4 changes: 3 additions & 1 deletion editor/debugger/editor_debugger_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ class EditorDebuggerServer : public RefCounted {

static void register_protocol_handler(const String &p_protocol, CreateServerFunc p_func);
static EditorDebuggerServer *create(const String &p_protocol);

virtual String get_uri() const = 0;
virtual void poll() = 0;
virtual Error start(const String &p_uri = "") = 0;
virtual Error start(const String &p_uri) = 0;
virtual void stop() = 0;
virtual bool is_active() const = 0;
virtual bool is_connection_available() const = 0;
Expand Down
12 changes: 2 additions & 10 deletions editor/editor_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2315,8 +2315,6 @@ void EditorNode::_run(bool p_current, const String &p_custom) {
play_custom_scene_button->set_icon(gui_base->get_theme_icon(SNAME("PlayCustom"), SNAME("EditorIcons")));

String run_filename;
String args;
bool skip_breakpoints;

if (p_current || (editor_data.get_edited_scene_root() && p_custom != String() && p_custom == editor_data.get_edited_scene_root()->get_scene_file_path())) {
Node *scene = editor_data.get_edited_scene_root();
Expand Down Expand Up @@ -2371,17 +2369,11 @@ void EditorNode::_run(bool p_current, const String &p_custom) {
make_bottom_panel_item_visible(log);
}

List<String> breakpoints;
editor_data.get_editor_breakpoints(&breakpoints);

args = ProjectSettings::get_singleton()->get("editor/run/main_run_args");
skip_breakpoints = EditorDebuggerNode::get_singleton()->is_skip_breakpoints();

EditorDebuggerNode::get_singleton()->start();
Error error = editor_run.run(run_filename, args, breakpoints, skip_breakpoints);
Error error = editor_run.run(run_filename);
if (error != OK) {
EditorDebuggerNode::get_singleton()->stop();
show_accept(TTR("Could not start subprocess!"), TTR("OK"));
show_accept(TTR("Could not start subprocess(es)!"), TTR("OK"));
return;
}

Expand Down
30 changes: 16 additions & 14 deletions editor/editor_run.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "editor_run.h"

#include "core/config/project_settings.h"
#include "editor/editor_node.h"
#include "editor_settings.h"
#include "servers/display_server.h"

Expand All @@ -42,20 +43,17 @@ String EditorRun::get_running_scene() const {
return running_scene;
}

Error EditorRun::run(const String &p_scene, const String &p_custom_args, const List<String> &p_breakpoints, const bool &p_skip_breakpoints) {
Error EditorRun::run(const String &p_scene) {
List<String> args;

String resource_path = ProjectSettings::get_singleton()->get_resource_path();
String remote_host = EditorSettings::get_singleton()->get("network/debug/remote_host");
int remote_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port");

if (resource_path != "") {
if (!resource_path.is_empty()) {
args.push_back("--path");
args.push_back(resource_path.replace(" ", "%20"));
}

args.push_back("--remote-debug");
args.push_back("tcp://" + remote_host + ":" + String::num(remote_port));
args.push_back(EditorDebuggerNode::get_singleton()->get_server_uri());

args.push_back("--allow_focus_steal_pid");
args.push_back(itos(OS::get_singleton()->get_process_id()));
Expand Down Expand Up @@ -162,10 +160,13 @@ Error EditorRun::run(const String &p_scene, const String &p_custom_args, const L
} break;
}

if (p_breakpoints.size()) {
List<String> breakpoints;
EditorNode::get_editor_data().get_editor_breakpoints(&breakpoints);

if (!breakpoints.is_empty()) {
args.push_back("--breakpoints");
String bpoints;
for (const List<String>::Element *E = p_breakpoints.front(); E; E = E->next()) {
for (const List<String>::Element *E = breakpoints.front(); E; E = E->next()) {
bpoints += E->get().replace(" ", "%20");
if (E->next()) {
bpoints += ",";
Expand All @@ -175,7 +176,7 @@ Error EditorRun::run(const String &p_scene, const String &p_custom_args, const L
args.push_back(bpoints);
}

if (p_skip_breakpoints) {
if (EditorDebuggerNode::get_singleton()->is_skip_breakpoints()) {
args.push_back("--skip-breakpoints");
}

Expand All @@ -185,20 +186,21 @@ Error EditorRun::run(const String &p_scene, const String &p_custom_args, const L

String exec = OS::get_singleton()->get_executable_path();

if (p_custom_args != "") {
const String raw_custom_args = ProjectSettings::get_singleton()->get("editor/run/main_run_args");
if (!raw_custom_args.is_empty()) {
// Allow the user to specify a command to run, similar to Steam's launch options.
// In this case, Godot will no longer be run directly; it's up to the underlying command
// to run it. For instance, this can be used on Linux to force a running project
// to use Optimus using `prime-run` or similar.
// Example: `prime-run %command% --time-scale 0.5`
const int placeholder_pos = p_custom_args.find("%command%");
const int placeholder_pos = raw_custom_args.find("%command%");

Vector<String> custom_args;

if (placeholder_pos != -1) {
// Prepend executable-specific custom arguments.
// If nothing is placed before `%command%`, behave as if no placeholder was specified.
Vector<String> exec_args = p_custom_args.substr(0, placeholder_pos).split(" ", false);
Vector<String> exec_args = raw_custom_args.substr(0, placeholder_pos).split(" ", false);
if (exec_args.size() >= 1) {
exec = exec_args[0];
exec_args.remove_at(0);
Expand All @@ -214,13 +216,13 @@ Error EditorRun::run(const String &p_scene, const String &p_custom_args, const L
}

// Append Godot-specific custom arguments.
custom_args = p_custom_args.substr(placeholder_pos + String("%command%").size()).split(" ", false);
custom_args = raw_custom_args.substr(placeholder_pos + String("%command%").size()).split(" ", false);
for (int i = 0; i < custom_args.size(); i++) {
args.push_back(custom_args[i].replace(" ", "%20"));
}
} else {
// Append Godot-specific custom arguments.
custom_args = p_custom_args.split(" ", false);
custom_args = raw_custom_args.split(" ", false);
for (int i = 0; i < custom_args.size(); i++) {
args.push_back(custom_args[i].replace(" ", "%20"));
}
Expand Down
2 changes: 1 addition & 1 deletion editor/editor_run.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class EditorRun {
public:
Status get_status() const;
String get_running_scene() const;
Error run(const String &p_scene, const String &p_custom_args, const List<String> &p_breakpoints, const bool &p_skip_breakpoints = false);
Error run(const String &p_scene);
void run_native_notify() { status = STATUS_PLAY; }
void stop();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class GDScriptLanguageServer : public EditorPlugin {
bool started = false;
bool use_thread = false;
String host = "127.0.0.1";
int port = 6008;
int port = 6005;
static void thread_main(void *p_userdata);

private:
Expand Down
34 changes: 32 additions & 2 deletions modules/websocket/editor_debugger_server_websocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
#include "editor_debugger_server_websocket.h"

#include "core/config/project_settings.h"
#include "editor/editor_log.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
#include "modules/websocket/remote_debugger_peer_websocket.h"

Expand All @@ -48,19 +50,47 @@ void EditorDebuggerServerWebSocket::poll() {
server->poll();
}

String EditorDebuggerServerWebSocket::get_uri() const {
return endpoint;
}

Error EditorDebuggerServerWebSocket::start(const String &p_uri) {
// Default host and port
String bind_host = (String)EditorSettings::get_singleton()->get("network/debug/remote_host");
int bind_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port");
String bind_host = EditorSettings::get_singleton()->get("network/debug/remote_host");

// Optionally override
if (!p_uri.is_empty() && p_uri != "ws://") {
String scheme, path;
Error err = p_uri.parse_url(scheme, bind_host, bind_port, path);
ERR_FAIL_COND_V(err != OK, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(!bind_host.is_valid_ip_address() && bind_host != "*", ERR_INVALID_PARAMETER);
}

// Set up the server
server->set_bind_ip(bind_host);
Vector<String> compatible_protocols;
compatible_protocols.push_back("binary"); // compatibility with EMSCRIPTEN TCP-to-WebSocket layer.
return server->listen(bind_port, compatible_protocols);

// Try listening on ports
const int max_attempts = 5;
for (int attempt = 1;; ++attempt) {
const Error err = server->listen(bind_port, compatible_protocols);
if (err == OK) {
break;
}
if (attempt >= max_attempts) {
EditorNode::get_log()->add_message(vformat("Cannot listen on port %d, remote debugging unavailable.", bind_port), EditorLog::MSG_TYPE_ERROR);
return err;
}
int last_port = bind_port++;
EditorNode::get_log()->add_message(vformat("Cannot listen on port %d, trying %d instead.", last_port, bind_port), EditorLog::MSG_TYPE_WARNING);
}

// Endpoint that the client should connect to
endpoint = vformat("ws://%s:%d", bind_host, bind_port);

return OK;
}

void EditorDebuggerServerWebSocket::stop() {
Expand Down
14 changes: 8 additions & 6 deletions modules/websocket/editor_debugger_server_websocket.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,21 @@ class EditorDebuggerServerWebSocket : public EditorDebuggerServer {
private:
Ref<WebSocketServer> server;
List<int> pending_peers;
String endpoint;

public:
static EditorDebuggerServer *create(const String &p_protocol);

void _peer_connected(int p_peer, String p_protocol);
void _peer_disconnected(int p_peer, bool p_was_clean);

void poll() override;
Error start(const String &p_uri) override;
void stop() override;
bool is_active() const override;
bool is_connection_available() const override;
Ref<RemoteDebuggerPeer> take_connection() override;
virtual void poll() override;
virtual String get_uri() const override;
virtual Error start(const String &p_uri = "") override;
virtual void stop() override;
virtual bool is_active() const override;
virtual bool is_connection_available() const override;
virtual Ref<RemoteDebuggerPeer> take_connection() override;

EditorDebuggerServerWebSocket();
~EditorDebuggerServerWebSocket();
Expand Down

0 comments on commit de7873c

Please sign in to comment.