Fixed ReadMapList not seeing maps in all valveFS paths (bug 5715, r=asherkin).

This commit is contained in:
Ryan Stecker 2013-07-03 23:23:05 -04:00
parent 66790254ac
commit 6847c8eec0
7 changed files with 98 additions and 36 deletions

View File

@ -42,7 +42,7 @@ using namespace SourceMod;
* Add 1 to the RHS of this expression to bump the intercom file
* This is to prevent mismatching core/logic binaries
*/
#define SM_LOGIC_MAGIC (0x0F47C0DE - 17)
#define SM_LOGIC_MAGIC (0x0F47C0DE - 18)
#if defined SM_LOGIC
class IVEngineServer
@ -55,6 +55,20 @@ public:
virtual void ServerCommand(const char *cmd) = 0;
};
typedef int FileFindHandle_t;
#if defined SM_LOGIC
class IFileSystem
#else
class IFileSystem_Logic
#endif
{
public:
virtual const char *FindFirstEx(const char *pWildCard, const char *pPathID, FileFindHandle_t *pHandle) = 0;
virtual const char *FindNext(FileFindHandle_t handle) = 0;
virtual void FindClose(FileFindHandle_t handle) = 0;
};
namespace SourceMod
{
class ISourceMod;
@ -74,6 +88,7 @@ namespace SourceMod
}
class IVEngineServer;
class IFileSystem;
class ConVar;
struct ServerGlobals
@ -91,6 +106,7 @@ struct sm_core_t
ISourceMod *sm;
ILibrarySys *libsys;
IVEngineServer *engine;
IFileSystem *filesystem;
IShareSys *sharesys;
IRootConsole *rootmenu;
IPluginManager *pluginsys;

View File

@ -37,6 +37,7 @@
#include <ILibrarySys.h>
#include <ITextParsers.h>
#include <ISourceMod.h>
#include "stringutil.h"
using namespace SourceHook;
@ -349,51 +350,39 @@ public:
if ((success && pNewArray == NULL)
|| (!success && ((flags & MAPLIST_FLAG_MAPSFOLDER) == MAPLIST_FLAG_MAPSFOLDER)))
{
char path[255];
IDirectory *pDir;
pNewArray = new CellArray(64);
free_new_array = true;
g_pSM->BuildPath(Path_Game, path, sizeof(path), "maps");
if ((pDir = libsys->OpenDirectory(path)) != NULL)
cell_t *blk;
FileFindHandle_t findHandle;
const char *fileName = smcore.filesystem->FindFirstEx("maps/*.bsp", "GAME", &findHandle);
while (fileName)
{
char *ptr;
cell_t *blk;
char buffer[PLATFORM_MAX_PATH];
while (pDir->MoreFiles())
UTIL_StripExtension(fileName, buffer, sizeof(buffer));
if (!engine->IsMapValid(buffer))
{
if (!pDir->IsEntryFile()
|| strcmp(pDir->GetEntryName(), ".") == 0
|| strcmp(pDir->GetEntryName(), "..") == 0)
{
pDir->NextEntry();
continue;
}
smcore.strncopy(buffer, pDir->GetEntryName(), sizeof(buffer));
if ((ptr = strstr(buffer, ".bsp")) == NULL || ptr[4] != '\0')
{
pDir->NextEntry();
continue;
}
*ptr = '\0';
if (!engine->IsMapValid(buffer))
{
pDir->NextEntry();
continue;
}
if ((blk = pNewArray->push()) == NULL)
{
pDir->NextEntry();
continue;
}
smcore.strncopy((char *)blk, buffer, 255);
pDir->NextEntry();
fileName = smcore.filesystem->FindNext(findHandle);
continue;
}
libsys->CloseDirectory(pDir);
if ((blk = pNewArray->push()) == NULL)
{
fileName = smcore.filesystem->FindNext(findHandle);
continue;
}
smcore.strncopy((char *)blk, buffer, 255);
fileName = smcore.filesystem->FindNext(findHandle);
}
smcore.filesystem->FindClose(findHandle);
/* Remove the array if there were no items. */
if (pNewArray->size() == 0)
{

View File

@ -303,3 +303,35 @@ size_t UTIL_DecodeHexString(unsigned char *buffer, size_t maxlength, const char
return written;
}
#define PATHSEPARATOR(c) ((c) == '\\' || (c) == '/')
void UTIL_StripExtension(const char *in, char *out, int outSize)
{
// Find the last dot. If it's followed by a dot or a slash, then it's part of a
// directory specifier like ../../somedir/./blah.
// scan backward for '.'
int end = strlen(in) - 1;
while (end > 0 && in[end] != '.' && !PATHSEPARATOR(in[end]))
{
--end;
}
if (end > 0 && !PATHSEPARATOR(in[end]) && end < outSize)
{
int nChars = min(end, outSize-1);
if (out != in)
{
memcpy(out, in, nChars);
}
out[nChars] = 0;
}
else
{
// nothing found
if (out != in)
{
strncopy(out, in, outSize);
}
}
}

View File

@ -40,5 +40,7 @@ char *UTIL_ReplaceEx(char *subject, size_t maxLen, const char *search, size_t se
const char *replace, size_t replaceLen, bool caseSensitive = true);
size_t UTIL_DecodeHexString(unsigned char *buffer, size_t maxlength, const char *hexstr);
void UTIL_StripExtension(const char *in, char *out, int outSize);
#endif /* _INCLUDE_SOURCEMOD_COMMON_STRINGUTIL_H_ */

View File

@ -90,6 +90,25 @@ public:
static VEngineServer_Logic logic_engine;
class VFileSystem_Logic : public IFileSystem_Logic
{
public:
const char *FindFirstEx(const char *pWildCard, const char *pPathID, FileFindHandle_t *pHandle)
{
return filesystem->FindFirstEx(pWildCard, pPathID, pHandle);
}
const char *FindNext(FileFindHandle_t handle)
{
return filesystem->FindNext(handle);
}
void FindClose(FileFindHandle_t handle)
{
filesystem->FindClose(handle);
}
};
static VFileSystem_Logic logic_filesystem;
static void add_natives(sp_nativeinfo_t *natives)
{
g_pCoreNatives->AddNatives(natives);
@ -200,6 +219,7 @@ static sm_core_t core_bridge =
&g_SourceMod,
&g_LibSys,
reinterpret_cast<IVEngineServer*>(&logic_engine),
reinterpret_cast<IFileSystem*>(&logic_filesystem),
&g_ShareSys,
&g_RootMenu,
&g_PluginSys,

View File

@ -50,6 +50,7 @@ CallClass<IVEngineServer> *enginePatch = NULL;
CallClass<IServerGameDLL> *gamedllPatch = NULL;
IPlayerInfoManager *playerinfo = NULL;
IBaseFileSystem *basefilesystem = NULL;
IFileSystem *filesystem = NULL;
IEngineSound *enginesound = NULL;
IServerPluginHelpers *serverpluginhelpers = NULL;
IServerPluginCallbacks *vsp_interface = NULL;
@ -68,6 +69,7 @@ bool SourceMod_Core::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen
GET_V_IFACE_CURRENT(GetEngineFactory, gameevents, IGameEventManager2, INTERFACEVERSION_GAMEEVENTSMANAGER2);
GET_V_IFACE_CURRENT(GetEngineFactory, engrandom, IUniformRandomStream, VENGINE_SERVER_RANDOM_INTERFACE_VERSION);
GET_V_IFACE_CURRENT(GetFileSystemFactory, basefilesystem, IBaseFileSystem, BASEFILESYSTEM_INTERFACE_VERSION);
GET_V_IFACE_CURRENT(GetFileSystemFactory, filesystem, IFileSystem, FILESYSTEM_INTERFACE_VERSION);
GET_V_IFACE_CURRENT(GetEngineFactory, enginesound, IEngineSound, IENGINESOUND_SERVER_INTERFACE_VERSION);
GET_V_IFACE_CURRENT(GetEngineFactory, serverpluginhelpers, IServerPluginHelpers, INTERFACEVERSION_ISERVERPLUGINHELPERS);

View File

@ -99,6 +99,7 @@ extern SourceHook::CallClass<IServerGameDLL> *gamedllPatch;
extern IUniformRandomStream *engrandom;
extern IPlayerInfoManager *playerinfo;
extern IBaseFileSystem *basefilesystem;
extern IFileSystem *filesystem;
extern IEngineSound *enginesound;
extern IServerPluginHelpers *serverpluginhelpers;
extern IServerPluginCallbacks *vsp_interface;