diff --git a/Client/mods/deathmatch/logic/lua/CLuaMain.h b/Client/mods/deathmatch/logic/lua/CLuaMain.h index 976d8791d47..5729f6d2972 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaMain.h +++ b/Client/mods/deathmatch/logic/lua/CLuaMain.h @@ -78,10 +78,10 @@ class CLuaMain //: public CClient bool IsOOPEnabled() { return m_bEnableOOP; } - void InitPackageStorage(lua_State* L); // Create a psuedo package.loaded table - void GetPackage(lua_State* L, SString& strName); // Push the package value to the top of the stack - void SetPackage(lua_State* L, SString& strName); // Set the package to the value at the top of the stack - bool LoadLuaLib(lua_State* L, SString strName, SString& strError); // Load a lua library of a given name + void InitPackageStorage(lua_State* L); // Create a psuedo package.loaded table + void GetPackage(lua_State* L, SString& strName); // Push the package value to the top of the stack + void SetPackage(lua_State* L, SString& strName); // Set the package to the value at the top of the stack + bool LoadLuaLib(lua_State* L, SString strName, SString& strError, bool& bEmpty); // Load a lua library of a given name private: void InitSecurity(); diff --git a/Server/mods/deathmatch/logic/lua/CLuaMain.cpp b/Server/mods/deathmatch/logic/lua/CLuaMain.cpp index 30128498330..74539286e2a 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaMain.cpp +++ b/Server/mods/deathmatch/logic/lua/CLuaMain.cpp @@ -686,7 +686,7 @@ bool CLuaMain::LoadClib(lua_State* L, SString strName, SString& strError) if (!FileExists(strPath)) { - strError += "error loading module " + strName + " from file " + strPath + ":\n\t The specified module could not be found"; + strError += "#3: " + ConformPath(strPath, "modules/"); return false; } @@ -696,14 +696,14 @@ bool CLuaMain::LoadClib(lua_State* L, SString strName, SString& strError) !g_pGame->GetACLManager()->CanObjectUseRight(m_pResource->GetName().c_str(), CAccessControlListGroupObject::OBJECT_TYPE_RESOURCE, strName.c_str(), CAccessControlListRight::RIGHT_TYPE_MODULE, false)) { - strError += "error loading module " + strName + " from file " + strPath + ":\n\t ACL access denied. Grant \"module." + strName + - "\" right to resource " + m_pResource->GetName(); + strError = "could not load module '" + strName + "' from file " + ConformPath(strPath, "modules/") + ":\n\t ACL access denied. Grant \"module." + + strName + "\" right to resource " + m_pResource->GetName(); return false; } if (!luaL_loader_C(L, strName.c_str(), strPath.c_str()) || lua_type(L, -1) == LUA_TNIL) { - strError += "error loading module " + strName + " from file " + strPath + ":\n\t Failed to load module"; + strError = "failed to load module '" + strName + "' from file " + ConformPath(strPath, "modules/"); return false; } diff --git a/Server/mods/deathmatch/logic/lua/CLuaMain.h b/Server/mods/deathmatch/logic/lua/CLuaMain.h index 419a1cd2523..35c99d5e315 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaMain.h +++ b/Server/mods/deathmatch/logic/lua/CLuaMain.h @@ -108,11 +108,11 @@ class CLuaMain //: public CClient static int LuaLoadBuffer(lua_State* L, const char* buff, size_t sz, const char* name); static int OnUndump(const char* p, size_t n); - void InitPackageStorage(lua_State* L); // Create a psuedo package.loaded table - void GetPackage(lua_State* L, SString& strName); // Push the package value to the top of the stack - void SetPackage(lua_State* L, SString& strName); // Set the package to the value at the top of the stack - bool LoadLuaLib(lua_State* L, SString strName, SString& strError); // Load a lua library of a given name - bool LoadClib(lua_State* L, SString strName, SString& strError); // Load a C Lib of a given name + void InitPackageStorage(lua_State* L); // Create a psuedo package.loaded table + void GetPackage(lua_State* L, SString& strName); // Push the package value to the top of the stack + void SetPackage(lua_State* L, SString& strName); // Set the package to the value at the top of the stack + bool LoadLuaLib(lua_State* L, SString strName, SString& strError, bool& bEmpty); // Load a lua library of a given name + bool LoadClib(lua_State* L, SString strName, SString& strError); // Load a C Lib of a given name private: void InitSecurity(); diff --git a/Shared/mods/deathmatch/logic/lua/CLuaMain.Shared.cpp b/Shared/mods/deathmatch/logic/lua/CLuaMain.Shared.cpp index 1b292c051f5..455d2a624ec 100644 --- a/Shared/mods/deathmatch/logic/lua/CLuaMain.Shared.cpp +++ b/Shared/mods/deathmatch/logic/lua/CLuaMain.Shared.cpp @@ -91,7 +91,7 @@ void CLuaMain::GetPackage(lua_State* L, SString& strName) // Load a Lua lib of a given name // /////////////////////////////////////////////////////////////// -bool CLuaMain::LoadLuaLib(lua_State* L, SString strName, SString& strError) +bool CLuaMain::LoadLuaLib(lua_State* L, SString strName, SString& strError, bool& bEmpty) { SString strPath = strName; // Name format shouldn't include slashes. Subdirs are dots. @@ -106,6 +106,7 @@ bool CLuaMain::LoadLuaLib(lua_State* L, SString strName, SString& strError) #endif std::vector buffer; + strError = "error loading module '" + strName + "' from locations:\n\t"; // Try /?.lua SString strFilePath = PathJoin(strResPath, strPath + ".lua"); if (FileExists(strFilePath)) @@ -113,7 +114,7 @@ bool CLuaMain::LoadLuaLib(lua_State* L, SString strName, SString& strError) else { // Don't use a format string for safety, so we construct the error by hand - strError += "error loading module " + strName + " from file " + strFilePath + ":\n\t The specified module could not be found"; + strError += "#1: " + ConformPath(strFilePath, "resources/") + "\n\t"; // Try /?/init.lua strFilePath = PathJoin(strResPath, strPath, "init.lua"); @@ -121,8 +122,7 @@ bool CLuaMain::LoadLuaLib(lua_State* L, SString strName, SString& strError) FileLoad(strFilePath, buffer); else { - strError += "\n"; - strError += "error loading module " + strName + " from file " + strFilePath + ":\n\t The specified module could not be found"; + strError += "#2: " + ConformPath(strFilePath, "resources/") + "\n\t"; return false; } } @@ -137,7 +137,8 @@ bool CLuaMain::LoadLuaLib(lua_State* L, SString strName, SString& strError) if (lua_type(L, -1) == LUA_TNIL) { - strError += "error loading module " + strName + " from file " + strFilePath + ":\n\t Module didn't return a value"; + strError = "module '" + strName + "' in location " + ConformPath(strFilePath, "resources/") + " didn't return a value."; + bEmpty = true; return false; } @@ -145,7 +146,10 @@ bool CLuaMain::LoadLuaLib(lua_State* L, SString strName, SString& strError) return true; } else - strError += "error loading module " + strName + " from file " + strFilePath + ":\n\t Error loading script file"; + { + strError = "could not load module '" + strName + "' from file " + ConformPath(strFilePath, "resources/") + ": File is empty."; + bEmpty = true; + } return false; } diff --git a/Shared/mods/deathmatch/logic/luadefs/CLuaUtilDefs.cpp b/Shared/mods/deathmatch/logic/luadefs/CLuaUtilDefs.cpp index c4b14e5e3d1..c2d537eaacc 100644 --- a/Shared/mods/deathmatch/logic/luadefs/CLuaUtilDefs.cpp +++ b/Shared/mods/deathmatch/logic/luadefs/CLuaUtilDefs.cpp @@ -732,6 +732,7 @@ int CLuaUtilDefs::Require(lua_State* luaVM) if (!argStream.HasErrors()) { SString strError = ""; + bool bEmpty = false; // Check if package exists already, if so load it // stack: ["moduleName"] pLuaMain->GetPackage(luaVM, strMod); // stack: ["moduleName",pkgModule/nil] @@ -740,10 +741,16 @@ int CLuaUtilDefs::Require(lua_State* luaVM) lua_pop(luaVM, 1); // stack: ["moduleName"] // Check whether the appropriate pure lua module exists - if (pLuaMain->LoadLuaLib(luaVM, strMod, strError)) // stack: ["moduleName",pkgLuaMod/nil] + if (pLuaMain->LoadLuaLib(luaVM, strMod, strError, bEmpty)) // stack: ["moduleName",pkgLuaMod/nil] return 1; + + if (bEmpty) + { + m_pScriptDebugging->LogCustom(luaVM, strError); + lua_pushboolean(luaVM, false); + return 1; + } #ifndef MTA_CLIENT - strError += "\n"; // Check if a C library exists if (pLuaMain->LoadClib(luaVM, strMod, strError)) // stack: ["moduleName",fncModule/nil] return 1; diff --git a/Shared/sdk/SharedUtil.Misc.h b/Shared/sdk/SharedUtil.Misc.h index b6edd31699f..2b4807ac7e7 100644 --- a/Shared/sdk/SharedUtil.Misc.h +++ b/Shared/sdk/SharedUtil.Misc.h @@ -209,6 +209,8 @@ namespace SharedUtil // SString ConformResourcePath(const char* szRes, bool bConvertToUnixPathSep = false); + SString ConformPath(const char* szRes, SString szPath, bool bConvertToUnixPathSep = false); + // // string stuff // diff --git a/Shared/sdk/SharedUtil.Misc.hpp b/Shared/sdk/SharedUtil.Misc.hpp index 45311dc544c..5b707775553 100644 --- a/Shared/sdk/SharedUtil.Misc.hpp +++ b/Shared/sdk/SharedUtil.Misc.hpp @@ -1448,6 +1448,43 @@ SString SharedUtil::ConformResourcePath(const char* szRes, bool bConvertToUnixPa return strText; } +SString SharedUtil::ConformPath(const char* szRes, SString szPath, bool bConvertToUnixPathSep) +{ + SString strText = szRes ? szRes : ""; + char cPathSep; + + // Handle which path sep char +#ifdef WIN32 + if (!bConvertToUnixPathSep) + { + cPathSep = '\\'; + szPath = szPath.Replace("/", "\\"); + strText = strText.Replace("/", "\\"); + } + else +#endif + { + cPathSep = '/'; + szPath = szPath.Replace("\\", "/"); + strText = strText.Replace("\\", "/"); + } + + // Remove up to first occurrence + int iPos = strText.find(szPath); + if (iPos >= 0) + return SString("%s%s", szPath.c_str(), strText.substr(iPos + szPath.length()).c_str()); + + if (strText.substr(0, 3) == "...") + { + // Remove up to first '/' + int iPos = strText.find(cPathSep); + if (iPos >= 0) + return SString("%s%s", szPath.c_str(), strText.substr(iPos + 1).c_str()); + } + + return strText; +} + namespace SharedUtil { CArgMap::CArgMap(const SString& strArgSep, const SString& strPartsSep, const SString& strExtraDisallowedChars)