From 63753c5e8405837931510b8da648dc75d4970fe1 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 22 Nov 2013 20:11:24 +0100 Subject: [PATCH] Added cFile:GetFolderContents(). Fix 162. --- MCServer/Plugins/APIDump/APIDesc.lua | 21 +++++---- MCServer/Plugins/Debuggers/Debuggers.lua | 11 +++++ source/LuaState.cpp | 33 +++++++++++++ source/LuaState.h | 7 ++- source/ManualBindings.cpp | 27 +++++++++++ source/OSSupport/File.cpp | 60 ++++++++++++++++++++++++ source/OSSupport/File.h | 3 ++ source/PluginLua.cpp | 6 +-- source/PluginManager.cpp | 4 +- source/StringUtils.cpp | 49 ------------------- source/StringUtils.h | 3 -- 11 files changed, 155 insertions(+), 69 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 11b0aeff7..8591d9aa4 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -927,22 +927,23 @@ end cFile = { Desc = [[ - Provides helper functions for manipulating and querying the filesystem. Most functions are called - directly on the cFile class itself: + Provides helper functions for manipulating and querying the filesystem. Most functions are static, + so they should be called directly on the cFile class itself:
 cFile:Delete("/usr/bin/virus.exe");
 

]], Functions = { - Copy = { Params = "SrcFileName, DstFileName", Return = "bool", Notes = "Copies a single file to a new destination. Returns true if successful. Fails if the destination already exists." }, - CreateFolder = { Params = "FolderName", Return = "bool", Notes = "Creates a new folder. Returns true if successful." }, - Delete = { Params = "FileName", Return = "bool", Notes = "Deletes the specified file. Returns true if successful." }, - Exists = { Params = "FileName", Return = "bool", Notes = "Returns true if the specified file exists." }, - GetSize = { Params = "FileName", Return = "number", Notes = "Returns the size of the file, or -1 on failure." }, - IsFile = { Params = "Path", Return = "bool", Notes = "Returns true if the specified path points to an existing file." }, - IsFolder = { Params = "Path", Return = "bool", Notes = "Returns true if the specified path points to an existing folder." }, - Rename = { Params = "OrigPath, NewPath", Return = "bool", Notes = "Renames a file or a folder. Returns true if successful. Undefined result if NewPath already exists." }, + Copy = { Params = "SrcFileName, DstFileName", Return = "bool", Notes = "(STATIC) Copies a single file to a new destination. Returns true if successful. Fails if the destination already exists." }, + CreateFolder = { Params = "FolderName", Return = "bool", Notes = "(STATIC) Creates a new folder. Returns true if successful." }, + Delete = { Params = "FileName", Return = "bool", Notes = "(STATIC) Deletes the specified file. Returns true if successful." }, + Exists = { Params = "FileName", Return = "bool", Notes = "(STATIC) Returns true if the specified file exists." }, + GetFolderContents = { Params = "FolderName", Return = "array table of strings", Notes = "(STATIC) Returns the contents of the specified folder, as an array table of strings. Each filesystem object is listed. Use the IsFile() and IsFolder() functions to determine the object type." }, + GetSize = { Params = "FileName", Return = "number", Notes = "(STATIC) Returns the size of the file, or -1 on failure." }, + IsFile = { Params = "Path", Return = "bool", Notes = "(STATIC) Returns true if the specified path points to an existing file." }, + IsFolder = { Params = "Path", Return = "bool", Notes = "(STATIC) Returns true if the specified path points to an existing folder." }, + Rename = { Params = "OrigPath, NewPath", Return = "bool", Notes = "(STATIC) Renames a file or a folder. Returns true if successful. Undefined result if NewPath already exists." }, }, }, -- cFile diff --git a/MCServer/Plugins/Debuggers/Debuggers.lua b/MCServer/Plugins/Debuggers/Debuggers.lua index 682a54676..c9a610f71 100644 --- a/MCServer/Plugins/Debuggers/Debuggers.lua +++ b/MCServer/Plugins/Debuggers/Debuggers.lua @@ -51,6 +51,8 @@ function Initialize(Plugin) PM:BindCommand("/fr", "debuggers", HandleFurnaceRecipe, "- Shows the furnace recipe for the currently held item"); PM:BindCommand("/ff", "debuggers", HandleFurnaceFuel, "- Shows how long the currently held item would burn in a furnace"); + Plugin:AddWebTab("Debuggers", HandleRequest_Debuggers); + -- Enable the following line for BlockArea / Generator interface testing: -- PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHUNK_GENERATED); @@ -943,3 +945,12 @@ end + +function HandleRequest_Debuggers(a_Request) + local FolderContents = cFile:GetFolderContents("./"); + return "

The following objects have been returned by cFile:GetFolderContents():

"; +end + + + + diff --git a/source/LuaState.cpp b/source/LuaState.cpp index ba60ed67d..644f4972c 100644 --- a/source/LuaState.cpp +++ b/source/LuaState.cpp @@ -871,6 +871,39 @@ bool cLuaState::CheckParamNumber(int a_StartParam, int a_EndParam) +bool cLuaState::CheckParamString(int a_StartParam, int a_EndParam) +{ + ASSERT(IsValid()); + + if (a_EndParam < 0) + { + a_EndParam = a_StartParam; + } + + tolua_Error tolua_err; + for (int i = a_StartParam; i <= a_EndParam; i++) + { + if (tolua_isstring(m_LuaState, i, 0, &tolua_err)) + { + continue; + } + // Not the correct parameter + lua_Debug entry; + VERIFY(lua_getstack(m_LuaState, 0, &entry)); + VERIFY(lua_getinfo (m_LuaState, "n", &entry)); + AString ErrMsg = Printf("#ferror in function '%s'.", (entry.name != NULL) ? entry.name : "?"); + tolua_error(m_LuaState, ErrMsg.c_str(), &tolua_err); + return false; + } // for i - Param + + // All params checked ok + return true; +} + + + + + bool cLuaState::CheckParamEnd(int a_Param) { tolua_Error tolua_err; diff --git a/source/LuaState.h b/source/LuaState.h index 8586a251b..aa71ee226 100644 --- a/source/LuaState.h +++ b/source/LuaState.h @@ -770,12 +770,15 @@ public: /// Returns true if the specified parameters on the stack are of the specified usertype; also logs warning if not. Used for regular functions bool CheckParamUserType(int a_StartParam, const char * a_UserType, int a_EndParam = -1); - /// Returns true if the specified parameters on the stack are a table; also logs warning if not + /// Returns true if the specified parameters on the stack are tables; also logs warning if not bool CheckParamTable(int a_StartParam, int a_EndParam = -1); - /// Returns true if the specified parameters on the stack are a number; also logs warning if not + /// Returns true if the specified parameters on the stack are numbers; also logs warning if not bool CheckParamNumber(int a_StartParam, int a_EndParam = -1); + /// Returns true if the specified parameters on the stack are strings; also logs warning if not + bool CheckParamString(int a_StartParam, int a_EndParam = -1); + /// Returns true if the specified parameter on the stack is nil (indicating an end-of-parameters) bool CheckParamEnd(int a_Param); diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp index f3325f25c..967b03ee7 100644 --- a/source/ManualBindings.cpp +++ b/source/ManualBindings.cpp @@ -171,6 +171,29 @@ cPluginLua * GetLuaPlugin(lua_State * L) +static int tolua_cFile_GetFolderContents(lua_State * tolua_S) +{ + cLuaState LuaState(tolua_S); + if ( + !LuaState.CheckParamUserTable(1, "cFile") || + !LuaState.CheckParamString (2) || + !LuaState.CheckParamEnd (3) + ) + { + return 0; + } + + AString Folder = (AString)tolua_tocppstring(LuaState, 1, 0); + + AStringVector Contents = cFile::GetFolderContents(Folder); + LuaState.Push(Contents); + return 1; +} + + + + + template< class Ty1, class Ty2, @@ -2153,6 +2176,10 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_function(tolua_S, "LOGWARNING", tolua_LOGWARN); tolua_function(tolua_S, "LOGERROR", tolua_LOGERROR); + tolua_beginmodule(tolua_S, "cFile"); + tolua_function(tolua_S, "GetFolderContents", tolua_cFile_GetFolderContents); + tolua_endmodule(tolua_S); + tolua_beginmodule(tolua_S, "cHopperEntity"); tolua_function(tolua_S, "GetOutputBlockPos", tolua_cHopperEntity_GetOutputBlockPos); tolua_endmodule(tolua_S); diff --git a/source/OSSupport/File.cpp b/source/OSSupport/File.cpp index d2eea498a..86276bd79 100644 --- a/source/OSSupport/File.cpp +++ b/source/OSSupport/File.cpp @@ -360,6 +360,66 @@ bool cFile::CreateFolder(const AString & a_FolderPath) +AStringVector cFile::GetFolderContents(const AString & a_Folder) +{ + AStringVector AllFiles; + + #ifdef _WIN32 + + // If the folder name doesn't contain the terminating slash / backslash, add it: + AString FileFilter = a_Folder; + if ( + !FileFilter.empty() && + (FileFilter[FileFilter.length() - 1] != '\\') && + (FileFilter[FileFilter.length() - 1] != '/') + ) + { + FileFilter.push_back('\\'); + } + + // Find all files / folders: + FileFilter.append("*.*"); + HANDLE hFind; + WIN32_FIND_DATA FindFileData; + if ((hFind = FindFirstFile(FileFilter.c_str(), &FindFileData)) != INVALID_HANDLE_VALUE) + { + do + { + AllFiles.push_back(FindFileData.cFileName); + } while (FindNextFile(hFind, &FindFileData)); + FindClose(hFind); + } + + #else // _WIN32 + + DIR * dp; + struct dirent *dirp; + if (*a_Directory == 0) + { + a_Directory = "."; + } + if ((dp = opendir(a_Directory)) == NULL) + { + LOGERROR("Error (%i) opening directory \"%s\"\n", errno, a_Directory ); + } + else + { + while ((dirp = readdir(dp)) != NULL) + { + AllFiles.push_back(dirp->d_name); + } + closedir(dp); + } + + #endif // else _WIN32 + + return AllFiles; +} + + + + + int cFile::Printf(const char * a_Fmt, ...) { AString buf; diff --git a/source/OSSupport/File.h b/source/OSSupport/File.h index cfb3a2019..70f81c8d2 100644 --- a/source/OSSupport/File.h +++ b/source/OSSupport/File.h @@ -123,6 +123,9 @@ public: // tolua_end + /// Returns the list of all items in the specified folder (files, folders, nix pipes, whatever's there). + static AStringVector GetFolderContents(const AString & a_Folder); // Exported in ManualBindings.cpp + int Printf(const char * a_Fmt, ...); private: diff --git a/source/PluginLua.cpp b/source/PluginLua.cpp index 03aefb098..23d079b05 100644 --- a/source/PluginLua.cpp +++ b/source/PluginLua.cpp @@ -86,11 +86,11 @@ bool cPluginLua::Initialize(void) lua_setglobal(m_LuaState, "g_Plugin"); } - std::string PluginPath = FILE_IO_PREFIX + GetLocalDirectory() + "/"; + std::string PluginPath = FILE_IO_PREFIX + GetLocalFolder() + "/"; // Load all files for this plugin, and execute them - AStringList Files = GetDirectoryContents(PluginPath.c_str()); - for (AStringList::const_iterator itr = Files.begin(); itr != Files.end(); ++itr) + AStringVector Files = cFile::GetFolderContents(PluginPath.c_str()); + for (AStringVector::const_iterator itr = Files.begin(); itr != Files.end(); ++itr) { if (itr->rfind(".lua") == AString::npos) { diff --git a/source/PluginManager.cpp b/source/PluginManager.cpp index 0a9f5b9d3..e08ebe503 100644 --- a/source/PluginManager.cpp +++ b/source/PluginManager.cpp @@ -72,8 +72,8 @@ void cPluginManager::FindPlugins(void) ++itr; } - AStringList Files = GetDirectoryContents(PluginsPath.c_str()); - for (AStringList::const_iterator itr = Files.begin(); itr != Files.end(); ++itr) + AStringVector Files = cFile::GetFolderContents(PluginsPath.c_str()); + for (AStringVector::const_iterator itr = Files.begin(); itr != Files.end(); ++itr) { if ((*itr == ".") || (*itr == "..") || (!cFile::IsFolder(PluginsPath + *itr))) { diff --git a/source/StringUtils.cpp b/source/StringUtils.cpp index d52b1323f..f7aeeed26 100644 --- a/source/StringUtils.cpp +++ b/source/StringUtils.cpp @@ -270,55 +270,6 @@ void ReplaceString(AString & iHayStack, const AString & iNeedle, const AString & -AStringList GetDirectoryContents(const char * a_Directory) -{ - AStringList AllFiles; - - #ifdef _WIN32 - - AString FileFilter = AString(a_Directory) + "*.*"; - HANDLE hFind; - WIN32_FIND_DATA FindFileData; - - if ((hFind = FindFirstFile(FileFilter.c_str(), &FindFileData)) != INVALID_HANDLE_VALUE) - { - do - { - AllFiles.push_back(FindFileData.cFileName); - } while (FindNextFile(hFind, &FindFileData)); - FindClose(hFind); - } - - #else // _WIN32 - - DIR * dp; - struct dirent *dirp; - if (*a_Directory == 0) - { - a_Directory = "."; - } - if ((dp = opendir(a_Directory)) == NULL) - { - LOGERROR("Error (%i) opening directory \"%s\"\n", errno, a_Directory ); - } - else - { - while ((dirp = readdir(dp)) != NULL) - { - AllFiles.push_back(dirp->d_name); - } - closedir(dp); - } - - #endif // else _WIN32 - - return AllFiles; -} - - - - - // Converts a stream of BE shorts into UTF-8 string; returns a ref to a_UTF8 AString & RawBEToUTF8(short * a_RawData, int a_NumShorts, AString & a_UTF8) { diff --git a/source/StringUtils.h b/source/StringUtils.h index ec9ba96ce..3917cc4ec 100644 --- a/source/StringUtils.h +++ b/source/StringUtils.h @@ -57,9 +57,6 @@ extern unsigned int RateCompareString(const AString & s1, const AString & s2 ); /// Replaces *each* occurence of iNeedle in iHayStack with iReplaceWith extern void ReplaceString(AString & iHayStack, const AString & iNeedle, const AString & iReplaceWith); // tolua_export -/// Returns the list of all items in the specified directory (files, folders, nix pipes, whatever's there) -extern AStringList GetDirectoryContents(const char * a_Directory); - /// Converts a stream of BE shorts into UTF-8 string; returns a ref to a_UTF8 extern AString & RawBEToUTF8(short * a_RawData, int a_NumShorts, AString & a_UTF8);