From c6f137da7816143687eda2ea3f0eae84e0ea8dda Mon Sep 17 00:00:00 2001 From: div0 Date: Thu, 15 Nov 2007 15:51:16 +0000 Subject: [PATCH] mapinfo: add a search function to find a map with a given unique prefix git-svn-id: svn://svn.icculus.org/nexuiz/trunk@2955 f962a42d-fe04-0410-a3ab-8c8b0445ebaa --- data/qcsrc/common/mapinfo.qc | 36 ++++++++++++++++++++++++++++++++++++ data/qcsrc/common/mapinfo.qh | 3 +++ data/qcsrc/server/g_world.qc | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) diff --git a/data/qcsrc/common/mapinfo.qc b/data/qcsrc/common/mapinfo.qc index 284447ea4..c3a44f6a2 100644 --- a/data/qcsrc/common/mapinfo.qc +++ b/data/qcsrc/common/mapinfo.qc @@ -311,3 +311,39 @@ float MapInfo_Get_ByName(string pFilename, float pAllowGenerate) dprint("Map ", pFilename, " supports no game types, ignored\n"); return 0; } + +string MapInfo_FixName(string s) +{ + // if there is exactly one map of prefix s, return it + // if not, return the null string + // note that DP sorts glob results... so I can use a binary search + string match; + float l, r, m, cmp; + l = 0; + r = MapInfo_count; + // invariants: r is behind s, l-1 is equal or before + while(l != r) + { + m = floor((l + r) / 2); + cmp = strcasecmp(_MapInfo_GlobItem(HugeSetOfIntegers_get(_MapInfo_filtered, m)), s); + if(cmp == 0) + return s; // found and good + if(cmp < 0) + l = m + 1; // l-1 is before s + else + r = m; // behind s + } + // r == l, so: l is behind s, l-1 is before + // SO: if there is any, l is the one with the right prefix + // and l+1 may be one too + if(l == MapInfo_count) + return string_null; // no match, behind last item + match = _MapInfo_GlobItem(HugeSetOfIntegers_get(_MapInfo_filtered, l)); + if(!startsWith(match, s)) + return string_null; // wrong prefix + if(l == MapInfo_count - 1) + return match; // last one, nothing can follow => unique + if(startsWith(_MapInfo_GlobItem(HugeSetOfIntegers_get(_MapInfo_filtered, l + 1)), s)) + return string_null; // ambigous match + return match; +} diff --git a/data/qcsrc/common/mapinfo.qh b/data/qcsrc/common/mapinfo.qh index dd605fcac..1dd5f7e0f 100644 --- a/data/qcsrc/common/mapinfo.qh +++ b/data/qcsrc/common/mapinfo.qh @@ -31,3 +31,6 @@ float MapInfo_Get_ByID(float i); // 1 on success, 0 on failure // load info about a map by name into the MapInfo_Map_* globals float MapInfo_Get_ByName(string s, float allowGenerate); // 1 on success, 0 on failure, 2 if it autogenerated a mapinfo file + +// look for a map by a prefix, returns the actual map name on success, string_null on failure or ambigous match +string MapInfo_FixName(string s); diff --git a/data/qcsrc/server/g_world.qc b/data/qcsrc/server/g_world.qc index 62b562615..7677d9bc0 100644 --- a/data/qcsrc/server/g_world.qc +++ b/data/qcsrc/server/g_world.qc @@ -397,17 +397,23 @@ float IsSameGametype(string mapcfgname) { string gt; gt = GetGametype(); +#ifdef MAPINFO +#else if(substring(mapcfgname, 0, strlen(gt) + 1) == strcat(gt, "_")) return TRUE; return FALSE; +#endif } string getmapname_stored; string GetMapname() { +#ifdef MAPINFO +#else if(getmapname_stored == "") getmapname_stored = strzone(strcat(GetGametype(), "_", mapname)); return getmapname_stored; +#endif } float Map_Count, Map_Current; @@ -465,11 +471,14 @@ float MapHasRightSize(string map) return TRUE; } +#ifdef MAPINFO +#else string Map_Filename(float position) { // FIXME unused return strcat("maps/", argv(position), ".mapcfg"); } +#endif string strwords(string s, float w) { @@ -509,8 +518,11 @@ float(float position, float pass) Map_Check = if(Map_IsRecent(map_next)) return 0; } +#ifdef MAPINFO +#else filename = Map_Filename(position); if(TryFile(filename)) +#endif { if(pass == 2) return 1; @@ -557,7 +569,10 @@ void() Map_Goto = { Map_MarkAsRecent(getmapname_stored); GameResetCfg(); +#ifdef MAPINFO +#else localcmd(strcat("exec \"maps/", getmapname_stored ,".mapcfg\"\n")); +#endif } // return codes of map selectors: @@ -650,7 +665,10 @@ void() Maplist_Init = if(Map_Count == 0) { bprint( "Maplist is empty! Resetting it to default map list.\n" ); +#ifdef MAPINFO +#else cvar_set("g_maplist", temp = cvar_string("g_maplist_defaultlist")); +#endif Map_Count = tokenize(temp); } if(Map_Count == 0) @@ -728,7 +746,10 @@ float() DoNextMapOverride = return TRUE; } if(cvar_string("nextmap") != "") +#ifdef MAPINFO +#else if(TryFile(strcat("maps/", cvar_string("nextmap"), ".mapcfg"))) +#endif { Map_Goto_SetStr(cvar_string("nextmap")); Map_Goto(); @@ -767,7 +788,10 @@ void() GotoNextMap = if(allowReset) { bprint( "Maplist contains no single playable map! Resetting it to default map list.\n" ); +#ifdef MAPINFO +#else cvar_set("g_maplist", cvar_string("g_maplist_defaultlist")); +#endif } else { @@ -1738,7 +1762,10 @@ string MapVote_Suggest(string m) if(Map_IsRecent(m)) return "This server does not allow for recent maps to be played again. Please be patient for some rounds."; +#ifdef MAPINFO +#else if(!TryFile(strcat("maps/", m, ".mapcfg"))) +#endif return "The map you suggested is not available on this server."; for(i = 0; i < mapvote_suggestion_ptr; ++i) if(mapvote_suggestions[i] == m) @@ -1794,7 +1821,10 @@ void MapVote_Init() if(mapvote_count == 0) { bprint( "Maplist contains no single playable map! Resetting it to default map list.\n" ); +#ifdef MAPINFO +#else cvar_set("g_maplist", cvar_string("g_maplist_defaultlist")); +#endif for(i = 0; i < 100 && mapvote_count < nmax; ++i) MapVote_AddVotable(GetNextMap(), FALSE); } @@ -2032,7 +2062,10 @@ void MapVote_Think() string GotoMap(string m) { +#ifdef MAPINFO +#else if(!TryFile(strcat("maps/", m, ".mapcfg"))) +#endif return "The map you chose is not available on this server."; cvar_set("nextmap", m); cvar_set("timelimit", "-1"); -- 2.39.2