Added support for "fuzzy" map names in L4D and later (bug 5599, r=asherkin).
Added support for "fuzzy" map names in L4D and later (
bug 5599, r=asherkin).
1.1 --- a/core/HalfLife2.cpp Wed Feb 13 22:25:15 2013 -0500
1.2 +++ b/core/HalfLife2.cpp Thu Feb 14 19:28:12 2013 -0500
1.3 @@ -1131,3 +1131,44 @@
1.4
1.5 return *(const char **)(((unsigned char *)pEntity) + offset);
1.6 }
1.7 +
1.8 +#if SOURCE_ENGINE >= SE_LEFT4DEAD
1.9 +static bool ResolveFuzzyMapName(const char *fuzzyName, char *outFullname, int size)
1.10 +{
1.11 + static ConCommand *pHelperCmd = g_pCVar->FindCommand("changelevel");
1.12 + if (!pHelperCmd || !pHelperCmd->CanAutoComplete())
1.13 + return false;
1.14 +
1.15 + static size_t helperCmdLen = strlen(pHelperCmd->GetName());
1.16 +
1.17 + CUtlVector<CUtlString> results;
1.18 + pHelperCmd->AutoCompleteSuggest(fuzzyName, results);
1.19 + if (results.Count() == 0)
1.20 + return false;
1.21 +
1.22 + // Results come back as you'd see in autocomplete. (ie. "changelevel fullmapnamehere"),
1.23 + // so skip ahead to start of map path/name
1.24 +
1.25 + // Like the engine, we're only going to deal with the first match.
1.26 +
1.27 + strncopy(outFullname, &results[0][helperCmdLen + 1], size);
1.28 +
1.29 + return true;
1.30 +}
1.31 +#endif
1.32 +
1.33 +bool CHalfLife2::IsMapValid(const char *map)
1.34 +{
1.35 + bool ret = engine->IsMapValid(map);
1.36 +#if SOURCE_ENGINE >= SE_LEFT4DEAD
1.37 + if (!ret)
1.38 + {
1.39 + static char szFuzzyName[PLATFORM_MAX_PATH];
1.40 + if (ResolveFuzzyMapName(map, szFuzzyName, sizeof(szFuzzyName)))
1.41 + {
1.42 + ret = engine->IsMapValid(szFuzzyName);
1.43 + }
1.44 + }
1.45 +#endif
1.46 + return ret;
1.47 +}
2.1 --- a/core/HalfLife2.h Wed Feb 13 22:25:15 2013 -0500
2.2 +++ b/core/HalfLife2.h Thu Feb 14 19:28:12 2013 -0500
2.3 @@ -148,6 +148,7 @@
2.4 ICommandLine *GetValveCommandLine();
2.5 const char *GetEntityClassname(edict_t *pEdict);
2.6 const char *GetEntityClassname(CBaseEntity *pEntity);
2.7 + bool IsMapValid(const char *map);
2.8 public:
2.9 void AddToFakeCliCmdQueue(int client, int userid, const char *cmd);
2.10 void ProcessFakeCliCmdQueue();
3.1 --- a/core/NextMap.cpp Wed Feb 13 22:25:15 2013 -0500
3.2 +++ b/core/NextMap.cpp Thu Feb 14 19:28:12 2013 -0500
3.3 @@ -31,6 +31,7 @@
3.4
3.5 #include "NextMap.h"
3.6 #include "Logger.h"
3.7 +#include "HalfLife2.h"
3.8 #include "sourcemm_api.h"
3.9 #include "sm_stringutil.h"
3.10 #include "sourcehook.h"
3.11 @@ -109,7 +110,7 @@
3.12
3.13 bool NextMapManager::SetNextMap(const char *map)
3.14 {
3.15 - if (!engine->IsMapValid(map))
3.16 + if (!g_HL2.IsMapValid(map))
3.17 {
3.18 return false;
3.19 }
3.20 @@ -133,7 +134,7 @@
3.21
3.22 const char *newmap = sm_nextmap.GetString();
3.23
3.24 - if (newmap[0] == 0 || !engine->IsMapValid(newmap))
3.25 + if (newmap[0] == 0 || !g_HL2.IsMapValid(newmap))
3.26 {
3.27 RETURN_META(MRES_IGNORED);
3.28 }
4.1 --- a/core/logic/smn_maplists.cpp Wed Feb 13 22:25:15 2013 -0500
4.2 +++ b/core/logic/smn_maplists.cpp Thu Feb 14 19:28:12 2013 -0500
4.3 @@ -33,6 +33,7 @@
4.4 #include <sm_trie_tpl.h>
4.5 #include "common_logic.h"
4.6 #include "CellArray.h"
4.7 +#include <IGameHelpers.h>
4.8 #include <ILibrarySys.h>
4.9 #include <ITextParsers.h>
4.10 #include <ISourceMod.h>
4.11 @@ -524,7 +525,7 @@
4.12 {
4.13 continue;
4.14 }
4.15 - if (!engine->IsMapValid(ptr))
4.16 + if (!gamehelpers->IsMapValid(ptr))
4.17 {
4.18 continue;
4.19 }
5.1 --- a/core/smn_halflife.cpp Wed Feb 13 22:25:15 2013 -0500
5.2 +++ b/core/smn_halflife.cpp Thu Feb 14 19:28:12 2013 -0500
5.3 @@ -63,7 +63,7 @@
5.4 char *map;
5.5 pContext->LocalToString(params[1], &map);
5.6
5.7 - return engine->IsMapValid(map);
5.8 + return g_HL2.IsMapValid(map);
5.9 }
5.10
5.11 static cell_t IsDedicatedServer(IPluginContext *pContext, const cell_t *params)
6.1 --- a/public/IGameHelpers.h Wed Feb 13 22:25:15 2013 -0500
6.2 +++ b/public/IGameHelpers.h Thu Feb 14 19:28:12 2013 -0500
6.3 @@ -308,6 +308,16 @@
6.4 * @return Pointer to the string, or NULL if bad pointer.
6.5 */
6.6 virtual const char *GetEntityClassname(CBaseEntity *pEntity) =0;
6.7 +
6.8 + /**
6.9 + * @brief Returns whether or not a map name is valid to use with the
6.10 + * engine's Changelevel functionality. It need not be an exact filename on
6.11 + * some engines. For a check on the exact name, use IVEngineServer::IsMapValid.
6.12 + *
6.13 + * @param map Map name.
6.14 + * @return True if valid, otherwise false.
6.15 + */
6.16 + virtual bool IsMapValid(const char *map) =0;
6.17 };
6.18 }
6.19