From 9ec0bee83d00734ae071ab3036f88ce40c2265b0 Mon Sep 17 00:00:00 2001 From: Tom J Nowell Date: Mon, 29 Jun 2026 15:34:36 +0100 Subject: [PATCH 1/3] LuaMenu: load LuaSocket socket.lua from the base VFS CLuaMenu::InitLuaSocket looked for a bare 'socket.lua' in the default VFS (SPRING_VFS_RAW_FIRST), which never resolved: the file actually ships in springcontent.sdz at LuaSocket/socket.lua. As a result the menu/lobby's LuaSocket layer failed to initialise and logged 'Error loading socket.lua', so Chobby could not connect to multiplayer servers. Load it from SPRING_VFS_BASE using the correct LuaSocket/socket.lua path, with a FileExists guard, exactly matching the working CLuaUI::InitLuaSocket. This is a general VFS-path bug, not platform-specific. Ported from ExaDev/RecoilEngine e9ca2151b5. --- rts/Lua/LuaMenu.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/rts/Lua/LuaMenu.cpp b/rts/Lua/LuaMenu.cpp index bafbc08be23..b812b95cbe5 100644 --- a/rts/Lua/LuaMenu.cpp +++ b/rts/Lua/LuaMenu.cpp @@ -137,8 +137,18 @@ string CLuaMenu::LoadFile(const string& name) const void CLuaMenu::InitLuaSocket(lua_State* L) { RECOIL_DETAILED_TRACY_ZONE; std::string code; - std::string filename = "socket.lua"; - CFileHandler f(filename); + // socket.lua ships in springcontent.sdz under LuaSocket/; load it from + // the base VFS exactly as CLuaUI::InitLuaSocket does. The previous path + // ("socket.lua", default VFS) never resolved, so the menu/lobby's + // LuaSocket support failed to initialise ("Error loading socket.lua"), + // breaking multiplayer server connections from Chobby. + std::string filename = "LuaSocket/socket.lua"; + CFileHandler f(filename, SPRING_VFS_BASE); + + if (!f.FileExists()) { + LOG_L(L_ERROR, "Error loading %s (file does not exist)", filename.c_str()); + return; + } LUA_OPEN_LIB(L, luaopen_socket_core); From bed80364bf9c2ebe3b4bbacfb69667c3d7544c2f Mon Sep 17 00:00:00 2001 From: Tom J Nowell Date: Tue, 30 Jun 2026 13:53:18 +0100 Subject: [PATCH 2/3] LuaSocket: hoist InitLuaSocket into CLuaHandle CLuaUI and CLuaMenu had identical InitLuaSocket bodies after #3078. Commonise as a protected CLuaHandle::InitLuaSocket so both inherit a single source of truth, per sprunk's review on #3078. A free LuaLibs::OpenLuaSocket would require making the privileged CLuaHandle::LoadCode public (templating a free function does not grant access to a protected member), so the protected-member form sprunk also OK'd is used instead. --- rts/Lua/LuaHandle.cpp | 31 +++++++++++++++++++++++++++++++ rts/Lua/LuaHandle.h | 1 + rts/Lua/LuaMenu.cpp | 27 --------------------------- rts/Lua/LuaMenu.h | 1 - rts/Lua/LuaUI.cpp | 20 -------------------- rts/Lua/LuaUI.h | 1 - 6 files changed, 32 insertions(+), 49 deletions(-) diff --git a/rts/Lua/LuaHandle.cpp b/rts/Lua/LuaHandle.cpp index 650a810499d..9e8c852cc72 100644 --- a/rts/Lua/LuaHandle.cpp +++ b/rts/Lua/LuaHandle.cpp @@ -41,6 +41,8 @@ #include "Sim/Units/UnitDef.h" #include "Sim/Weapons/Weapon.h" #include "Sim/Weapons/WeaponDef.h" +#include "System/FileSystem/FileHandler.h" +#include "System/FileSystem/VFSModes.h" #include "System/creg/SerializeLuaState.h" #include "System/Config/ConfigHandler.h" #include "System/EventHandler.h" @@ -56,6 +58,8 @@ #include "LuaInclude.h" +#include "lib/luasocket/src/luasocket.h" + #include #include #include @@ -549,6 +553,33 @@ bool CLuaHandle::LoadCode(lua_State* L, std::string code, const string& debug) } +void CLuaHandle::InitLuaSocket(lua_State* L) +{ + RECOIL_DETAILED_TRACY_ZONE; + std::string code; + // socket.lua ships in springcontent.sdz under LuaSocket/; load it from + // the base VFS. A previous menu/lobby path ("socket.lua", default VFS) + // never resolved, so LuaSocket support failed to initialise ("Error + // loading socket.lua"), breaking multiplayer server connections from + // Chobby. Shared by CLuaUI and CLuaMenu so both use the same path/mode. + std::string filename = "LuaSocket/socket.lua"; + CFileHandler f(filename, SPRING_VFS_BASE); + + if (!f.FileExists()) { + LOG_L(L_ERROR, "Error loading %s (file does not exist)", filename.c_str()); + return; + } + + LUA_OPEN_LIB(L, luaopen_socket_core); + + if (f.LoadStringData(code)) { + LoadCode(L, std::move(code), filename); + } else { + LOG_L(L_ERROR, "Error loading %s", filename.c_str()); + } +} + + int CLuaHandle::LoadStringData(lua_State* L) { RECOIL_DETAILED_TRACY_ZONE; diff --git a/rts/Lua/LuaHandle.h b/rts/Lua/LuaHandle.h index 5256825a2b6..97ddf4323c9 100644 --- a/rts/Lua/LuaHandle.h +++ b/rts/Lua/LuaHandle.h @@ -329,6 +329,7 @@ class CLuaHandle : public CEventClient bool AddBasicCalls(lua_State* L); bool AddCommonModules(lua_State* L); bool LoadCode(lua_State* L, std::string code, const std::string& debug); + void InitLuaSocket(lua_State* L); static bool AddEntriesToTable(lua_State* L, const char* name, bool (*entriesFunc)(lua_State*)); /// returns error code and sets traceback on error diff --git a/rts/Lua/LuaMenu.cpp b/rts/Lua/LuaMenu.cpp index b812b95cbe5..bce52197ec8 100644 --- a/rts/Lua/LuaMenu.cpp +++ b/rts/Lua/LuaMenu.cpp @@ -24,7 +24,6 @@ #include "System/FileSystem/FileHandler.h" #include "System/FileSystem/FileSystem.h" #include "System/Threading/SpringThreading.h" -#include "lib/luasocket/src/luasocket.h" #include "LuaUI.h" #include "System/Misc/TracyDefs.h" @@ -134,32 +133,6 @@ string CLuaMenu::LoadFile(const string& name) const } -void CLuaMenu::InitLuaSocket(lua_State* L) { - RECOIL_DETAILED_TRACY_ZONE; - std::string code; - // socket.lua ships in springcontent.sdz under LuaSocket/; load it from - // the base VFS exactly as CLuaUI::InitLuaSocket does. The previous path - // ("socket.lua", default VFS) never resolved, so the menu/lobby's - // LuaSocket support failed to initialise ("Error loading socket.lua"), - // breaking multiplayer server connections from Chobby. - std::string filename = "LuaSocket/socket.lua"; - CFileHandler f(filename, SPRING_VFS_BASE); - - if (!f.FileExists()) { - LOG_L(L_ERROR, "Error loading %s (file does not exist)", filename.c_str()); - return; - } - - LUA_OPEN_LIB(L, luaopen_socket_core); - - if (f.LoadStringData(code)) { - LoadCode(L, std::move(code), filename); - } else { - LOG_L(L_ERROR, "Error loading %s", filename.c_str()); - } -} - - bool CLuaMenu::RemoveSomeOpenGLFunctions(lua_State* L) { // remove some spring opengl functions that don't work preloading diff --git a/rts/Lua/LuaMenu.h b/rts/Lua/LuaMenu.h index 0c65859e90d..aa7a990475e 100644 --- a/rts/Lua/LuaMenu.h +++ b/rts/Lua/LuaMenu.h @@ -61,7 +61,6 @@ class CLuaMenu : public CLuaHandle static bool LoadUnsyncedReadFunctions(lua_State* L); static bool RemoveSomeOpenGLFunctions(lua_State* L); static bool PushGameVersion(lua_State* L); - void InitLuaSocket(lua_State* L); protected: QueuedAction queuedAction; }; diff --git a/rts/Lua/LuaUI.cpp b/rts/Lua/LuaUI.cpp index 01204219fa4..4b768f39f53 100644 --- a/rts/Lua/LuaUI.cpp +++ b/rts/Lua/LuaUI.cpp @@ -40,7 +40,6 @@ #include "System/Config/ConfigHandler.h" #include "System/StringUtil.h" #include "System/Threading/SpringThreading.h" -#include "lib/luasocket/src/luasocket.h" #include @@ -207,25 +206,6 @@ GetWatchDef(Explosion) SetWatchDef(Explosion) -void CLuaUI::InitLuaSocket(lua_State* L) { - std::string code; - std::string filename = "LuaSocket/socket.lua"; - CFileHandler f(filename, SPRING_VFS_BASE); - - if (!f.FileExists()) { - LOG_L(L_ERROR, "Error loading %s (file does not exist)", filename.c_str()); - return; - } - - LUA_OPEN_LIB(L, luaopen_socket_core); - - if (f.LoadStringData(code)) { - LoadCode(L, std::move(code), filename); - } else { - LOG_L(L_ERROR, "Error loading %s", filename.c_str()); - } -} - string CLuaUI::LoadFile(const string& name, const std::string& mode) const { CFileHandler f(name, mode); diff --git a/rts/Lua/LuaUI.h b/rts/Lua/LuaUI.h index 6ee9b2d1f73..dfe2b9ab2a4 100644 --- a/rts/Lua/LuaUI.h +++ b/rts/Lua/LuaUI.h @@ -83,7 +83,6 @@ class CLuaUI : public CLuaHandle string LoadFile(const string& name, const std::string& mode) const; bool LoadCFunctions(lua_State* L); - void InitLuaSocket(lua_State* L); bool BuildCmdDescTable(lua_State* L, const vector& cmds); bool GetLuaIntMap(lua_State* L, int index, spring::unordered_map& intList); From f0e6556411622013435ebaea9df83cc8ebcbaa60 Mon Sep 17 00:00:00 2001 From: sprunk Date: Tue, 30 Jun 2026 15:09:03 +0200 Subject: [PATCH 3/3] var scope liming + useless comment --- rts/Lua/LuaHandle.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/rts/Lua/LuaHandle.cpp b/rts/Lua/LuaHandle.cpp index 9e8c852cc72..6ae29a6f293 100644 --- a/rts/Lua/LuaHandle.cpp +++ b/rts/Lua/LuaHandle.cpp @@ -556,15 +556,9 @@ bool CLuaHandle::LoadCode(lua_State* L, std::string code, const string& debug) void CLuaHandle::InitLuaSocket(lua_State* L) { RECOIL_DETAILED_TRACY_ZONE; - std::string code; - // socket.lua ships in springcontent.sdz under LuaSocket/; load it from - // the base VFS. A previous menu/lobby path ("socket.lua", default VFS) - // never resolved, so LuaSocket support failed to initialise ("Error - // loading socket.lua"), breaking multiplayer server connections from - // Chobby. Shared by CLuaUI and CLuaMenu so both use the same path/mode. - std::string filename = "LuaSocket/socket.lua"; - CFileHandler f(filename, SPRING_VFS_BASE); + const std::string filename = "LuaSocket/socket.lua"; + CFileHandler f(filename, SPRING_VFS_BASE); if (!f.FileExists()) { LOG_L(L_ERROR, "Error loading %s (file does not exist)", filename.c_str()); return; @@ -572,6 +566,7 @@ void CLuaHandle::InitLuaSocket(lua_State* L) LUA_OPEN_LIB(L, luaopen_socket_core); + std::string code; if (f.LoadStringData(code)) { LoadCode(L, std::move(code), filename); } else {