From 6f1cb2a0a9bf9201d25fd98d6c7afe036fb0f433 Mon Sep 17 00:00:00 2001 From: ManDude <7569514+ManDude@users.noreply.github.com> Date: Sun, 2 Apr 2023 05:57:21 +0100 Subject: [PATCH] fix repl buffer overrun + use a different port for each game version (#2449) Fixes #2313 --- game/common/game_common_types.h | 2 ++ game/kernel/common/klisten.cpp | 3 ++- game/main.cpp | 6 ++++++ game/runtime.cpp | 4 +++- game/runtime.h | 1 + goal_src/jak2/engine/draw/drawable.gc | 2 +- goalc/compiler/Compiler.cpp | 1 + goalc/compiler/compilation/CompilerControl.cpp | 2 +- goalc/listener/Listener.cpp | 4 ++++ goalc/listener/Listener.h | 7 ++++--- 10 files changed, 25 insertions(+), 7 deletions(-) diff --git a/game/common/game_common_types.h b/game/common/game_common_types.h index 71c00bbdb2..a082909fbc 100644 --- a/game/common/game_common_types.h +++ b/game/common/game_common_types.h @@ -1,5 +1,6 @@ #pragma once +#include "common/listener_common.h" #include "common/versions.h" //! Supported languages. @@ -18,4 +19,5 @@ struct GameLaunchOptions { GameVersion game_version = GameVersion::Jak1; bool disable_display = false; bool disable_debug_vm = false; + int server_port = DECI2_PORT; }; diff --git a/game/kernel/common/klisten.cpp b/game/kernel/common/klisten.cpp index df321f2508..83c5b34986 100644 --- a/game/kernel/common/klisten.cpp +++ b/game/kernel/common/klisten.cpp @@ -19,9 +19,10 @@ void klisten_init_globals() { /*! * Flush pending messages. If debugging, will send to compiler, otherwise to stdout. + * Changed slightly, it will also print to stdout if there's no compiler connected. */ void ClearPending() { - if (!MasterDebug) { + if (!MasterDebug || !ListenerStatus) { // if we aren't debugging print the print buffer to stdout. if (PrintPending.offset != 0) { auto size = strlen(PrintBufArea.cast().c() + sizeof(ListenerMessageHeader)); diff --git a/game/main.cpp b/game/main.cpp index 6e256d34df..56797a2ee1 100644 --- a/game/main.cpp +++ b/game/main.cpp @@ -140,11 +140,15 @@ int main(int argc, char** argv) { bool disable_avx2 = false; bool disable_display = false; bool disable_debug_vm = false; + int port_number = -1; fs::path project_path_override; std::vector game_args; CLI::App app{"OpenGOAL Game Runtime"}; app.add_option("-g,--game", game_name, "The game name: 'jak1' or 'jak2'"); app.add_flag("-v,--verbose", verbose_logging, "Enable verbose logging on stdout"); + app.add_flag( + "--port", port_number, + "Specify port number for listener connection (default is 8112 for Jak 1 and 8113 for Jak 2)"); app.add_flag("--no-avx2", verbose_logging, "Disable AVX2 for testing"); app.add_flag("--no-display", disable_display, "Disable video display"); app.add_flag("--no-vm", disable_debug_vm, "Disable debug PS2 VM (defaulted to on)"); @@ -161,6 +165,8 @@ int main(int argc, char** argv) { game_options.disable_debug_vm = disable_debug_vm; game_options.disable_display = disable_display; game_options.game_version = game_name_to_version(game_name); + game_options.server_port = + port_number == -1 ? DECI2_PORT - 1 + (int)game_options.game_version : port_number; // Figure out if the CPU has AVX2 to enable higher performance AVX2 versions of functions. setup_cpu_info(); diff --git a/game/runtime.cpp b/game/runtime.cpp index 07dd2843fd..240add2998 100644 --- a/game/runtime.cpp +++ b/game/runtime.cpp @@ -71,6 +71,7 @@ u8* g_ee_main_mem = nullptr; std::thread::id g_main_thread_id = std::thread::id(); GameVersion g_game_version = GameVersion::Jak1; +int g_server_port = DECI2_PORT; namespace { @@ -86,7 +87,7 @@ void deci2_runner(SystemThreadInterface& iface) { std::function shutdown_callback = [&]() { return iface.get_want_exit(); }; // create and register server - Deci2Server server(shutdown_callback, DECI2_PORT); + Deci2Server server(shutdown_callback, DECI2_PORT - 1 + (int)g_game_version); ee::LIBRARY_sceDeci2_register(&server); // now its ok to continue with initialization @@ -318,6 +319,7 @@ RuntimeExitStatus exec_runtime(GameLaunchOptions game_options, int argc, const c bool enable_display = !game_options.disable_display; VM::use = !game_options.disable_debug_vm; g_game_version = game_options.game_version; + g_server_port = game_options.server_port; // set up discord stuff gStartTime = time(nullptr); diff --git a/game/runtime.h b/game/runtime.h index b545c9d717..23ffa33e4b 100644 --- a/game/runtime.h +++ b/game/runtime.h @@ -15,6 +15,7 @@ extern u8* g_ee_main_mem; extern GameVersion g_game_version; +extern int g_server_port; RuntimeExitStatus exec_runtime(GameLaunchOptions game_options, int argc, const char** argv); diff --git a/goal_src/jak2/engine/draw/drawable.gc b/goal_src/jak2/engine/draw/drawable.gc index 2e869ec432..b0c122dddc 100644 --- a/goal_src/jak2/engine/draw/drawable.gc +++ b/goal_src/jak2/engine/draw/drawable.gc @@ -1400,7 +1400,7 @@ (local-vars (a0-96 int) (a0-98 int)) (with-pp (when *slow-frame-rate* - (dotimes (v1-2 #xc35000) + (dotimes (v1-2 12800000) (nop!) (nop!) (nop!) diff --git a/goalc/compiler/Compiler.cpp b/goalc/compiler/Compiler.cpp index d5708be8af..207d7946b2 100644 --- a/goalc/compiler/Compiler.cpp +++ b/goalc/compiler/Compiler.cpp @@ -27,6 +27,7 @@ Compiler::Compiler(GameVersion version, m_repl(std::move(repl)), m_make(user_profile) { m_listener.add_debugger(&m_debugger); + m_listener.set_default_port(version); m_ts.add_builtin_types(m_version); m_global_env = std::make_unique(); m_none = std::make_unique(m_ts.make_typespec("none")); diff --git a/goalc/compiler/compilation/CompilerControl.cpp b/goalc/compiler/compilation/CompilerControl.cpp index 27a1dc0cb7..044c511ff7 100644 --- a/goalc/compiler/compilation/CompilerControl.cpp +++ b/goalc/compiler/compilation/CompilerControl.cpp @@ -197,7 +197,7 @@ Val* Compiler::compile_listen_to_target(const goos::Object& form, Env* env) { (void)env; std::string ip = "127.0.0.1"; - int port = DECI2_PORT; + int port = -1; bool got_port = false, got_ip = false; for_each_in_list(rest, [&](const goos::Object& o) { diff --git a/goalc/listener/Listener.cpp b/goalc/listener/Listener.cpp index c61bad89cf..d3a1df913f 100644 --- a/goalc/listener/Listener.cpp +++ b/goalc/listener/Listener.cpp @@ -87,6 +87,10 @@ bool Listener::is_connected() const { * Returns true if successfully connected. */ bool Listener::connect_to_target(int n_tries, const std::string& ip, int port) { + if (port == -1) { + port = m_default_port; + } + if (m_connected) { printf("already connected!\n"); return true; diff --git a/goalc/listener/Listener.h b/goalc/listener/Listener.h index ff58b00fe1..f49deecb1f 100644 --- a/goalc/listener/Listener.h +++ b/goalc/listener/Listener.h @@ -17,6 +17,7 @@ #include "common/common_types.h" #include "common/cross_os_debug/xdbg.h" +#include "common/versions.h" #include "common/listener_common.h" #include "goalc/debugger/Debugger.h" @@ -30,9 +31,7 @@ class Listener { static constexpr int BUFFER_SIZE = 32 * 1024 * 1024; Listener(); ~Listener(); - bool connect_to_target(int n_tries = 1, - const std::string& ip = "127.0.0.1", - int port = DECI2_PORT); + bool connect_to_target(int n_tries = 1, const std::string& ip = "127.0.0.1", int port = -1); void record_messages(ListenerMessageKind kind); int get_received_message_count(); std::vector stop_recording_messages(); @@ -43,6 +42,7 @@ class Listener { void send_code(std::vector& code, const std::optional& load_name = {}); void add_debugger(Debugger* debugger); bool most_recent_send_was_acked() const { return got_ack; } + void set_default_port(GameVersion v) { m_default_port = DECI2_PORT - 1 + (int)v; } MemoryMap build_memory_map(); private: @@ -53,6 +53,7 @@ class Listener { bool wait_for_ack(); void handle_output_message(const char* msg); + int m_default_port = DECI2_PORT; char* m_buffer = nullptr; //! buffer for incoming messages bool m_connected = false; //! do we think we are connected? bool receive_thread_running = false; //! is the receive thread unjoined?