Merge pull request #354 from powerlord/findmap-plugins

GetMapDisplayName and associated core plugin changes.
This commit is contained in:
Nicholas Hastings 2015-09-17 11:17:40 -04:00
commit c982cc9991
13 changed files with 195 additions and 50 deletions

View File

@ -1276,6 +1276,38 @@ SMFindMapResult CHalfLife2::FindMap(const char *pMapName, char *pFoundMap, size_
#endif
}
bool CHalfLife2::GetMapDisplayName(const char *pMapName, char *pDisplayname, size_t nMapNameMax)
{
SMFindMapResult result = FindMap(pMapName, pDisplayname, nMapNameMax);
if (result == SMFindMapResult::NotFound)
{
return false;
}
#if SOURCE_ENGINE == SE_CSGO
char *lastSlashPos;
// In CSGO, workshop maps show up as workshop/123456789/mapname
if (strncmp(pDisplayname, "workshop/", 9) == 0 && (lastSlashPos = strrchr(pDisplayname, '/')) != NULL)
{
ke::SafeSprintf(pDisplayname, nMapNameMax, "%s", &lastSlashPos[1]);
return true;
}
#elif SOURCE_ENGINE == SE_TF2
char *ugcPos;
// In TF2, workshop maps show up as workshop/mapname.ugc123456789
if (strncmp(pDisplayname, "workshop/", 9) == 0 && (ugcPos = strstr(pDisplayname, ".ugc")) != NULL)
{
// Overwrite the . with a nul and SafeSprintf will handle the rest
ugcPos[0] = '\0';
ke::SafeSprintf(pDisplayname, nMapNameMax, "%s", &pDisplayname[9]);
return true;
}
#endif
return true;
}
bool CHalfLife2::IsMapValid(const char *map)
{
if (!map || !map[0])

View File

@ -187,6 +187,7 @@ public: //IGameHelpers
bool IsMapValid(const char *map);
SMFindMapResult FindMap(char *pMapName, size_t nMapNameMax);
SMFindMapResult FindMap(const char *pMapName, char *pFoundMap = NULL, size_t nMapNameMax = 0);
bool GetMapDisplayName(const char *pMapName, char *pDisplayname, size_t nMapNameMax);
#if SOURCE_ENGINE >= SE_ORANGEBOX
string_t AllocPooledString(const char *pszValue);
#endif

View File

@ -82,6 +82,14 @@ static cell_t FindMap(IPluginContext *pContext, const cell_t *params)
return static_cast<cell_t>(g_HL2.FindMap(pMapname, pDestMap, params[3]));
}
static cell_t GetMapDisplayName(IPluginContext *pContext, const cell_t *params)
{
char *pMapname, *pDisplayname;
pContext->LocalToString(params[1], &pMapname);
pContext->LocalToString(params[2], &pDisplayname);
return static_cast<cell_t>(g_HL2.GetMapDisplayName(pMapname, pDisplayname, params[3]));
}
static cell_t IsDedicatedServer(IPluginContext *pContext, const cell_t *params)
{
return engine->IsDedicatedServer();
@ -642,6 +650,7 @@ REGISTER_NATIVES(halflifeNatives)
{"IsDedicatedServer", IsDedicatedServer},
{"IsMapValid", IsMapValid},
{"FindMap", FindMap},
{"GetMapDisplayName", GetMapDisplayName},
{"SetFakeClientConVar", SetFakeClientConVar},
{"SetRandomSeed", SetRandomSeed},
{"PrecacheModel", PrecacheModel},

View File

@ -211,6 +211,7 @@ public Action:Command_Nextmap(client, args)
}
else
{
GetMapDisplayName(map, map, sizeof(map));
ReplyToCommand(client, "[SM] %t", "Next Map", map);
}
@ -291,7 +292,8 @@ public OnClientSayCommand_Post(client, const String:command[], const String:sArg
{
char map[PLATFORM_MAX_PATH];
GetNextMap(map, sizeof(map));
GetMapDisplayName(map, map, sizeof(map));
if (g_Cvar_TriggerShow.IntValue)
{
if (mapchooser && EndOfMapVoteEnabled() && !HasEndOfMapVoteFinished())

View File

@ -116,7 +116,7 @@ public OnPluginStart()
OnAdminMenuReady(topmenu);
}
g_SelectedMaps = CreateArray(33);
g_SelectedMaps = CreateArray(ByteCountToCells(PLATFORM_MAX_PATH));
g_MapList = CreateMenu(MenuHandler_Map, MenuAction_DrawItem|MenuAction_Display);
g_MapList.SetTitle("%T", "Please select a map", LANG_SERVER);
@ -311,8 +311,11 @@ public Handler_VoteCallback(Menu menu, MenuAction action, param1, param2)
case (voteType:map):
{
// single-vote items don't use the display item
char displayName[PLATFORM_MAX_PATH];
GetMapDisplayName(item, displayName, sizeof(displayName));
LogAction(-1, -1, "Changing map to %s due to vote.", item);
PrintToChatAll("[SM] %t", "Changing map", item);
PrintToChatAll("[SM] %t", "Changing map", displayName);
new Handle:dp;
CreateDataTimer(5.0, Timer_ChangeMap, dp);
WritePackString(dp, item);

View File

@ -48,7 +48,7 @@ DisplayVoteMapMenu(client, mapCount, String:maps[5][])
if (mapCount == 1)
{
strcopy(g_voteInfo[VOTE_NAME], sizeof(g_voteInfo[]), maps[0]);
GetMapDisplayName(maps[0], g_voteInfo[VOTE_NAME], sizeof(g_voteInfo[]));
g_hVoteMenu.SetTitle("Change Map To");
g_hVoteMenu.AddItem(maps[0], "Yes");
@ -61,7 +61,9 @@ DisplayVoteMapMenu(client, mapCount, String:maps[5][])
g_hVoteMenu.SetTitle("Map Vote");
for (new i = 0; i < mapCount; i++)
{
g_hVoteMenu.AddItem(maps[i], maps[i]);
decl String:displayName[PLATFORM_MAX_PATH];
GetMapDisplayName(maps[i], displayName, sizeof(displayName));
g_hVoteMenu.AddItem(maps[i], displayName);
}
}
@ -288,8 +290,10 @@ int LoadMapList(Menu menu)
for (new i = 0; i < map_count; i++)
{
decl String:displayName[PLATFORM_MAX_PATH];
GetArrayString(g_map_array, i, map_name, sizeof(map_name));
menu.AddItem(map_name, map_name);
GetMapDisplayName(map_name, displayName, sizeof(displayName));
menu.AddItem(map_name, displayName);
}
return map_count;

View File

@ -167,6 +167,24 @@ native bool:IsMapValid(const String:map[]);
*/
native FindMapResult FindMap(const char[] map, char[] foundmap, int maxlen);
/**
* Get the display name of a workshop map.
*
* Note: You do not need to call FindMap first. This native will call FindMap internally.
*
* @param map Map name (usually same as map path relative to maps/ dir,
* excluding .bsp extension).
* @param displayName Map's display name, i.e. cp_mymapname or de_mymapname.
* If FindMap returns FindMap_PossiblyAvailable or FindMap_NotFound,
* the map cannot be resolved and this native will return false,
* but displayName will be a copy of map.
* @param maxlen Maximum length to write to displayName var.
* @return true if FindMap returns FindMap_Found, FindMap_FuzzyMatch, or
* FindMap_NonCanonical.
* false if FindMap returns FindMap_PossiblyAvailable or FindMap_NotFound.
*/
native bool GetMapDisplayName(const char[] map, char[] displayName, int maxlen);
/**
* Returns whether the server is dedicated.
*

View File

@ -74,6 +74,8 @@ ConVar g_Cvar_RunOffPercent;
Handle g_VoteTimer = null;
Handle g_RetryTimer = null;
// g_MapList stores unresolved names so we can resolve them after every map change in the workshop updates.
// g_OldMapList and g_NextMapList are resolved. g_NominateList depends on the nominations implementation.
/* Data Handles */
ArrayList g_MapList;
ArrayList g_NominateList;
@ -288,15 +290,18 @@ public Action Command_SetNextmap(int client, int args)
}
char map[PLATFORM_MAX_PATH];
char displayName[PLATFORM_MAX_PATH];
GetCmdArg(1, map, sizeof(map));
if (!IsMapValid(map))
if (FindMap(map, displayName, sizeof(displayName)) == FindMap_NotFound)
{
ReplyToCommand(client, "[SM] %t", "Map was not found", map);
return Plugin_Handled;
}
ShowActivity(client, "%t", "Changed Next Map", map);
GetMapDisplayName(displayName, displayName, sizeof(displayName));
ShowActivity(client, "%t", "Changed Next Map", displayName);
LogAction(client, -1, "\"%L\" changed nextmap to \"%s\"", client, map);
SetNextMap(map);
@ -321,7 +326,7 @@ void SetupTimeleftTimer()
int startTime = g_Cvar_StartTime.IntValue * 60;
if (time - startTime < 0 && g_Cvar_EndOfMapVote.BoolValue && !g_MapVoteCompleted && !g_HasVoteStarted)
{
InitiateVote(MapChange_MapEnd, null);
InitiateVote(MapChange_MapEnd, null);
}
else
{
@ -585,11 +590,12 @@ void InitiateVote(MapChange when, ArrayList inputlist=null)
/* Smaller of the two - It should be impossible for nominations to exceed the size though (cvar changed mid-map?) */
int nominationsToAdd = nominateCount >= voteSize ? voteSize : nominateCount;
for (int i=0; i<nominationsToAdd; i++)
{
char displayName[PLATFORM_MAX_PATH];
g_NominateList.GetString(i, map, sizeof(map));
g_VoteMenu.AddItem(map, map);
GetMapDisplayName(map, displayName, sizeof(displayName));
g_VoteMenu.AddItem(map, displayName);
RemoveStringFromArray(g_NextMapList, map);
/* Notify Nominations that this map is now free */
@ -630,7 +636,9 @@ void InitiateVote(MapChange when, ArrayList inputlist=null)
count++;
/* Insert the map and increment our count */
g_VoteMenu.AddItem(map, map);
char displayName[PLATFORM_MAX_PATH];
GetMapDisplayName(map, displayName, sizeof(displayName));
g_VoteMenu.AddItem(map, displayName);
i++;
}
@ -648,7 +656,9 @@ void InitiateVote(MapChange when, ArrayList inputlist=null)
if (IsMapValid(map))
{
g_VoteMenu.AddItem(map, map);
char displayName[PLATFORM_MAX_PATH];
GetMapDisplayName(map, displayName, sizeof(displayName));
g_VoteMenu.AddItem(map, displayName);
}
}
}
@ -689,7 +699,8 @@ public void Handler_VoteFinishedGeneric(Menu menu,
const int[][] item_info)
{
char map[PLATFORM_MAX_PATH];
menu.GetItem(item_info[0][VOTEINFO_ITEM_INDEX], map, sizeof(map));
char displayName[PLATFORM_MAX_PATH];
menu.GetItem(item_info[0][VOTEINFO_ITEM_INDEX], map, sizeof(map), _, displayName, sizeof(displayName));
if (strcmp(map, VOTE_EXTEND, false) == 0)
{
@ -771,7 +782,7 @@ public void Handler_VoteFinishedGeneric(Menu menu,
g_HasVoteStarted = false;
g_MapVoteCompleted = true;
PrintToChatAll("[SM] %t", "Nextmap Voting Finished", map, RoundToFloor(float(item_info[0][VOTEINFO_ITEM_VOTES])/float(num_votes)*100), num_votes);
PrintToChatAll("[SM] %t", "Nextmap Voting Finished", displayName, RoundToFloor(float(item_info[0][VOTEINFO_ITEM_VOTES])/float(num_votes)*100), num_votes);
LogAction(-1, -1, "Voting for next map has finished. Nextmap: %s.", map);
}
}
@ -940,11 +951,22 @@ bool RemoveStringFromArray(ArrayList array, char[] str)
void CreateNextVote()
{
ClearArray(g_NextMapList);
g_NextMapList.Clear();
char map[PLATFORM_MAX_PATH];
ArrayList tempMaps = g_MapList.Clone();
// tempMaps is a resolved map list
ArrayList tempMaps = new ArrayList(ByteCountToCells(PLATFORM_MAX_PATH));
for (int i = 0; i < g_MapList.Length; i++)
{
g_MapList.GetString(i, map, sizeof(map));
if (FindMap(map, map, sizeof(map)) != FindMap_NotFound)
{
tempMaps.PushString(map);
}
}
//GetCurrentMap always returns a resolved map
GetCurrentMap(map, sizeof(map));
RemoveStringFromArray(tempMaps, map);
@ -954,7 +976,7 @@ void CreateNextVote()
{
g_OldMapList.GetString(i, map, sizeof(map));
RemoveStringFromArray(tempMaps, map);
}
}
}
int limit = (g_Cvar_IncludeMaps.IntValue < tempMaps.Length ? g_Cvar_IncludeMaps.IntValue : tempMaps.Length);

View File

@ -153,7 +153,8 @@ void FindAndSetNextMap()
for (int i = 0; i < mapCount; i++)
{
g_MapList.GetString(i, mapName, sizeof(mapName));
if (strcmp(current, mapName, false) == 0)
if (FindMap(mapName, mapName, sizeof(mapName)) != FindMap_NotFound &&
strcmp(current, mapName, false) == 0)
{
g_MapPos = i;
break;

View File

@ -100,8 +100,11 @@ public void OnNominationRemoved(const char[] map, int owner)
{
int status;
char resolvedMap[PLATFORM_MAX_PATH];
FindMap(map, resolvedMap, sizeof(resolvedMap));
/* Is the map in our list? */
if (!g_mapTrie.GetValue(map, status))
if (!g_mapTrie.GetValue(resolvedMap, status))
{
return;
}
@ -112,7 +115,7 @@ public void OnNominationRemoved(const char[] map, int owner)
return;
}
g_mapTrie.SetValue(map, MAPSTATUS_ENABLED);
g_mapTrie.SetValue(resolvedMap, MAPSTATUS_ENABLED);
}
public Action Command_Addmap(int client, int args)
@ -124,31 +127,41 @@ public Action Command_Addmap(int client, int args)
}
char mapname[PLATFORM_MAX_PATH];
char resolvedMap[PLATFORM_MAX_PATH];
GetCmdArg(1, mapname, sizeof(mapname));
int status;
if (!g_mapTrie.GetValue(mapname, status))
if (FindMap(mapname, resolvedMap, sizeof(resolvedMap)) == FindMap_NotFound)
{
// We couldn't resolve the map entry to a filename, so...
ReplyToCommand(client, "%t", "Map was not found", mapname);
return Plugin_Handled;
}
NominateResult result = NominateMap(mapname, true, 0);
char displayName[PLATFORM_MAX_PATH];
GetMapDisplayName(resolvedMap, displayName, sizeof(displayName));
int status;
if (!g_mapTrie.GetValue(resolvedMap, status))
{
ReplyToCommand(client, "%t", "Map was not found", displayName);
return Plugin_Handled;
}
NominateResult result = NominateMap(resolvedMap, true, 0);
if (result > Nominate_Replaced)
{
/* We assume already in vote is the casue because the maplist does a Map Validity check and we forced, so it can't be full */
ReplyToCommand(client, "%t", "Map Already In Vote", mapname);
ReplyToCommand(client, "%t", "Map Already In Vote", displayName);
return Plugin_Handled;
}
g_mapTrie.SetValue(mapname, MAPSTATUS_DISABLED|MAPSTATUS_EXCLUDE_NOMINATED);
g_mapTrie.SetValue(resolvedMap, MAPSTATUS_DISABLED|MAPSTATUS_EXCLUDE_NOMINATED);
ReplyToCommand(client, "%t", "Map Inserted", mapname);
ReplyToCommand(client, "%t", "Map Inserted", displayName);
LogAction(client, -1, "\"%L\" inserted map \"%s\".", client, mapname);
return Plugin_Handled;
@ -187,10 +200,20 @@ public Action Command_Nominate(int client, int args)
char mapname[PLATFORM_MAX_PATH];
GetCmdArg(1, mapname, sizeof(mapname));
if (FindMap(mapname, mapname, sizeof(mapname)) == FindMap_NotFound)
{
// We couldn't resolve the map entry to a filename, so...
ReplyToCommand(client, "%t", "Map was not found", mapname);
return Plugin_Handled;
}
char displayName[PLATFORM_MAX_PATH];
GetMapDisplayName(mapname, displayName, sizeof(displayName));
int status;
if (!g_mapTrie.GetValue(mapname, status))
{
ReplyToCommand(client, "%t", "Map was not found", mapname);
ReplyToCommand(client, "%t", "Map was not found", displayName);
return Plugin_Handled;
}
@ -220,7 +243,7 @@ public Action Command_Nominate(int client, int args)
{
if (result == Nominate_AlreadyInVote)
{
ReplyToCommand(client, "%t", "Map Already In Vote", mapname);
ReplyToCommand(client, "%t", "Map Already In Vote", displayName);
}
else
{
@ -236,7 +259,7 @@ public Action Command_Nominate(int client, int args)
char name[MAX_NAME_LENGTH];
GetClientName(client, name, sizeof(name));
PrintToChatAll("[SM] %t", "Map Nominated", name, mapname);
PrintToChatAll("[SM] %t", "Map Nominated", name, displayName);
return Plugin_Continue;
}
@ -273,13 +296,17 @@ void BuildMapMenu()
GetCurrentMap(currentMap, sizeof(currentMap));
}
for (int i = 0; i < g_MapList.Length; i++)
{
int status = MAPSTATUS_ENABLED;
g_MapList.GetString(i, map, sizeof(map));
FindMap(map, map, sizeof(map));
char displayName[PLATFORM_MAX_PATH];
GetMapDisplayName(map, displayName, sizeof(displayName));
if (g_Cvar_ExcludeCurrent.BoolValue)
{
if (StrEqual(map, currentMap))
@ -297,7 +324,7 @@ void BuildMapMenu()
}
}
g_MapMenu.AddItem(map, map);
g_MapMenu.AddItem(map, displayName);
g_mapTrie.SetValue(map, status);
}
@ -312,8 +339,8 @@ public int Handler_MapSelectMenu(Menu menu, MenuAction action, int param1, int p
{
case MenuAction_Select:
{
char map[PLATFORM_MAX_PATH], name[MAX_NAME_LENGTH];
menu.GetItem(param2, map, sizeof(map));
char map[PLATFORM_MAX_PATH], name[MAX_NAME_LENGTH], displayName[PLATFORM_MAX_PATH];
menu.GetItem(param2, map, sizeof(map), _, displayName, sizeof(displayName));
GetClientName(param1, name, sizeof(name));
@ -335,11 +362,11 @@ public int Handler_MapSelectMenu(Menu menu, MenuAction action, int param1, int p
if (result == Nominate_Replaced)
{
PrintToChatAll("[SM] %t", "Map Nomination Changed", name, map);
PrintToChatAll("[SM] %t", "Map Nomination Changed", name, displayName);
return 0;
}
PrintToChatAll("[SM] %t", "Map Nominated", name, map);
PrintToChatAll("[SM] %t", "Map Nominated", name, displayName);
}
case MenuAction_DrawItem:
@ -366,8 +393,8 @@ public int Handler_MapSelectMenu(Menu menu, MenuAction action, int param1, int p
case MenuAction_DisplayItem:
{
char map[PLATFORM_MAX_PATH];
menu.GetItem(param2, map, sizeof(map));
char map[PLATFORM_MAX_PATH], displayName[PLATFORM_MAX_PATH];
menu.GetItem(param2, map, sizeof(map), _, displayName, sizeof(displayName));
int status;
@ -383,19 +410,19 @@ public int Handler_MapSelectMenu(Menu menu, MenuAction action, int param1, int p
{
if ((status & MAPSTATUS_EXCLUDE_CURRENT) == MAPSTATUS_EXCLUDE_CURRENT)
{
Format(display, sizeof(display), "%s (%T)", map, "Current Map", param1);
Format(display, sizeof(display), "%s (%T)", displayName, "Current Map", param1);
return RedrawMenuItem(display);
}
if ((status & MAPSTATUS_EXCLUDE_PREVIOUS) == MAPSTATUS_EXCLUDE_PREVIOUS)
{
Format(display, sizeof(display), "%s (%T)", map, "Recently Played", param1);
Format(display, sizeof(display), "%s (%T)", displayName, "Recently Played", param1);
return RedrawMenuItem(display);
}
if ((status & MAPSTATUS_EXCLUDE_NOMINATED) == MAPSTATUS_EXCLUDE_NOMINATED)
{
Format(display, sizeof(display), "%s (%T)", map, "Nominated", param1);
Format(display, sizeof(display), "%s (%T)", displayName, "Nominated", param1);
return RedrawMenuItem(display);
}
}

View File

@ -82,6 +82,7 @@ public void OnConfigsExecuted()
public Action Timer_RandomizeNextmap(Handle timer)
{
char map[PLATFORM_MAX_PATH];
char resolvedMap[PLATFORM_MAX_PATH];
bool oldMaps = false;
if (g_Cvar_ExcludeMaps.IntValue && g_MapList.Length > g_Cvar_ExcludeMaps.IntValue)
@ -89,16 +90,14 @@ public Action Timer_RandomizeNextmap(Handle timer)
oldMaps = true;
}
int b = GetRandomInt(0, g_MapList.Length - 1);
g_MapList.GetString(b, map, sizeof(map));
while (oldMaps && g_OldMapList.FindString(map) != -1)
do
{
b = GetRandomInt(0, g_MapList.Length - 1);
int b = GetRandomInt(0, g_MapList.Length - 1);
g_MapList.GetString(b, map, sizeof(map));
}
FindMap(map, resolvedMap, sizeof(resolvedMap));
} while (oldMaps && g_OldMapList.FindString(resolvedMap) != -1);
g_OldMapList.PushString(map);
g_OldMapList.PushString(resolvedMap);
SetNextMap(map);
if (g_OldMapList.Length > g_Cvar_ExcludeMaps.IntValue)

View File

@ -243,6 +243,8 @@ void StartRTV()
char map[PLATFORM_MAX_PATH];
if (GetNextMap(map, sizeof(map)))
{
GetMapDisplayName(map, map, sizeof(map));
PrintToChatAll("[SM] %t", "Changing Maps", map);
CreateTimer(5.0, Timer_ChangeMap, _, TIMER_FLAG_NO_MAPCHANGE);
g_InChange = true;

View File

@ -0,0 +1,25 @@
#include <sourcemod>
public void OnPluginStart()
{
RegServerCmd("test_mapdisplayname", test_mapdisplayname);
}
public Action test_mapdisplayname( int argc )
{
char mapName[PLATFORM_MAX_PATH];
GetCmdArg(1, mapName, sizeof(mapName));
char displayName[PLATFORM_MAX_PATH];
if (GetMapDisplayName(mapName, displayName, sizeof(displayName)))
{
PrintToServer("GetMapDisplayName says \"%s\" for \"%s\"", displayName, mapName);
}
else
{
PrintToServer("GetMapDisplayName says \"%s\" was not found or not resolved", mapName);
}
return Plugin_Handled;
}