using System; using System.Collections; using System.Collections.Generic; using System.IO; using Addon;
namespace GameTypeChanger { public class GameTypeChanger : CPlugin { // The array that aliases can be stored in public Dictionary<string, IList> aliases = new Dictionary<string, IList>();
// General variables public bool isDLC = false; public string mapName; public string gameType;
/// <summary> /// Executes when a client connects to the MW3 server. /// /// When a client does connect a list of map aliases will be constructed that will be used to /// determine if a chosen map is part of the DLC packs or a standard map that comes packaged /// with the game on a clean install. /// </summary> public override void OnServerLoad() { ServerPrint("\n Game type changer plugin loaded. Author: SgtLegend. Version 1.3\n");
// Create the map alias array aliases.Add("maps", new List<AliasListing>() { // Standard maps new AliasListing() { name = "lockdown", value = "std:mp_alpha" }, new AliasListing() { name = "bootleg", value = "std:mp_bootleg" }, new AliasListing() { name = "mission", value = "std:mp_bravo" }, new AliasListing() { name = "carbon", value = "std:mp_carbon" }, new AliasListing() { name = "dome", value = "std:mp_dome" }, new AliasListing() { name = "downturn", value = "std:mp_exchange" }, new AliasListing() { name = "hardhat", value = "std:mp_hardhat" }, new AliasListing() { name = "interchange", value = "std:mp_interchange" }, new AliasListing() { name = "fallen", value = "std:mp_lambeth" }, new AliasListing() { name = "bakaara", value = "std:mp_mogadishu" }, new AliasListing() { name = "resistance", value = "std:mp_paris" }, new AliasListing() { name = "arkaden", value = "std:mp_plaza2" }, new AliasListing() { name = "outpost", value = "std:mp_radar" }, new AliasListing() { name = "seatown", value = "std:mp_seatown" }, new AliasListing() { name = "underground", value = "std:mp_underground" }, new AliasListing() { name = "village", value = "std:mp_village" },
// DLC maps new AliasListing() { name = "aground", value = "dlc:mp_aground_ss" }, new AliasListing() { name = "blackbox", value = "dlc:mp_morningwood" }, new AliasListing() { name = "boardwalk", value = "dlc:mp_Boardwalk" }, new AliasListing() { name = "decommission", value = "dlc:mp_Shipbreaker" }, new AliasListing() { name = "erosion", value = "dlc:mp_courtyard_ss" }, new AliasListing() { name = "foundation", value = "dlc:mp_Foundation" }, new AliasListing() { name = "getaway", value = "dlc:mp_hillside_ss" }, new AliasListing() { name = "gulch", value = "dlc:mp_gulch" }, new AliasListing() { name = "liberation", value = "dlc:mp_park" }, new AliasListing() { name = "lookout", value = "dlc:mp_restrepo_ss" }, new AliasListing() { name = "terminal", value = "dlc:mp_terminal_cls" }, new AliasListing() { name = "oasis", value = "dlc:mp_Qadeem" }, new AliasListing() { name = "offshore", value = "dlc:mp_roughneck" }, new AliasListing() { name = "overwatch", value = "dlc:mp_overwatch" }, new AliasListing() { name = "parish", value = "dlc:mp_NOLA" }, new AliasListing() { name = "piazza", value = "dlc:mp_italy" }, new AliasListing() { name = "sanctuary", value = "dlc:mp_meteora" }, new AliasListing() { name = "uturn", value = "dlc:mp_burn_ss" }, new AliasListing() { name = "intersection", value = "dlc:mp_crosswalk_ss" }, new AliasListing() { name = "vortex", value = "dlc:mp_six_ss" },
});
// Get and set all the directories in the zone folder string[] zoneDirectories = Directory.GetDirectories("zone"); List<string> directories = new List<string>();
foreach (string directory in zoneDirectories) { if (!directory.Contains("dlc")) directories.Add(directory); }
aliases.Add("zones", directories); }
/// <summary> /// Listens for when a client types in the chat, currently it listens for "!gametype" and "!gt" /// which are two pre-defined chat commands that can be assigned using the permissions plugin /// otherwise everyone will be able to use them. /// </summary> /// <param name="Message"></param> /// <param name="Client"></param> /// <returns></returns> public override ChatType OnSay(string Message, ServerClient Client) { if (Message.StartsWith("!gametype") || Message.StartsWith("!gt")) { string[] split = Message.Split(' ');
// Do we have enough arguments? if (split.Length < 3) { TellClient(Client.ClientNum, "^1Usage: ^7!" + split[0] + " <map name> <dsr name>", true); return ChatType.ChatNone; }
// Set the map name and game type mapName = split[1].ToLower(); gameType = split[2];
// Are the required arguments empty? if (string.IsNullOrEmpty(mapName) || string.IsNullOrEmpty(gameType)) { TellClient(Client.ClientNum, (string.IsNullOrEmpty(mapName) ? "^1Enter a map name" : "^1Enter a game type DSR name"), true); return ChatType.ChatNone; }
// Sort through all the maps specified in the alias list and determine if the map name // the user has entered matches something in that list setMapNameAndIsDLC();
// Check if the specified map exists on the server and also check if the game type given // is on that exists within the admin folder bool isMapValid = checkIfTheMapExists(); bool isGameTypeValid = File.Exists(@"admin\" + gameType + ".dsr");
// Check if the custom playlist file we created still exists, if it does we need to // delete it off the server so the normal playlist can continue to work after the map // has been changed if (File.Exists(@"admin\gametypechanger.dspl")) { File.Delete(@"admin\gametypechanger.dspl"); }
// Create the new playlist file that we can use to force the game type createDSPLFileAndMessageTheAdmins();
return ChatType.ChatNone; }
return ChatType.ChatContinue; }
/// <summary> /// When the map changes the custom DSPL file we set will take control of the map rotation so we /// need to switch it back to the original DSPL file. /// /// There is a downside to this which is that we have to incur another map rotation call which now /// increments the total to "2" rotations. /// /// Resets the variables that may still have values from the last change. /// </summary> public override void OnMapChange() { isDLC = false; mapName = string.Empty; gameType = string.Empty;
/// <summary> /// Loops through all the pre-defined maps that were constructed while the server was connecting to /// the server and tries to determine which map the user has chosen using the switch game type commands /// </summary> private void setMapNameAndIsDLC() { foreach (AliasListing map in aliases["maps"]) { string[] mapDetails = map.value.Split(':');
// Check if the given map name matches the current map name if (mapName == map.name || mapName == mapDetails[1]) { mapName = mapDetails[1]; isDLC = (mapDetails[0] == "dlc"); break; } } }
/// <summary> /// Checks if the given map exists on the server using the list of directories that we discovered /// in the zone folder earlier. /// </summary> /// <returns></returns> private bool checkIfTheMapExists() { if ((isDLC && File.Exists(@"zone\dlc\" + mapName + ".ff")) || !isDLC) { if (!isDLC) { foreach (string directory in aliases["zones"]) { if (File.Exists(directory + @"\" + mapName + ".ff")) return true; } } else { return true; } }
return false; }
/// <summary> /// It also create the custom DSPL file needed to set the user selected map and game type set via /// the commands. /// /// Lets all the admins on the server know the map was just changed using "!gametype" or "!gt" and /// what game type was loaded during the change. /// </summary> private void createDSPLFileAndMessageTheAdmins() { using (StreamWriter file = new StreamWriter(@"admin\gametypechanger.dspl", true)) { file.WriteLine(string.Format("{0},{1},1", mapName, gameType));
// Issue the server command to change the map ServerCommand("sv_maprotation gametypechanger"); ServerCommand("start_map_rotate");
// Display a server message to let the user know the map and game type has changed. Admins ONLY! string adminXUIDs = GetServerCFG("Permission", "Admin_xuids", ""); List<ServerClient> clients = GetClients();
if (!string.IsNullOrEmpty(adminXUIDs)) { foreach (ServerClient client in clients) { if (adminXUIDs.Contains(client.XUID)) TellClient(client.ClientNum, string.Format("^5Map changed to ^7{0} ^5using ^7{1} as the game type", mapName, gameType), true); } } } } }
/// <summary> /// A re-usable structure array that can be used for map aliases etc... /// </summary> public struct AliasListing { public string name, value; } }
using System; using System.Collections; using System.Collections.Generic; using System.IO; using Addon;
namespace GameTypeChanger { public class GameTypeChanger : CPlugin { // The array that aliases can be stored in public Dictionary<string, IList> aliases = new Dictionary<string, IList>();
// General variables public bool isDLC = false; public string mapName; public string gameType;
/// <summary> /// Executes when a client connects to the MW3 server. /// /// When a client does connect a list of map aliases will be constructed that will be used to /// determine if a chosen map is part of the DLC packs or a standard map that comes packaged /// with the game on a clean install. /// </summary> public override void OnServerLoad() { ServerPrint("\n Game type changer plugin loaded. Author: SgtLegend. Version 1.3\n");
// Create the map alias array aliases.Add("maps", new List<AliasListing>() { // Standard maps new AliasListing() { name = "lockdown", value = "std:mp_alpha" }, new AliasListing() { name = "bootleg", value = "std:mp_bootleg" }, new AliasListing() { name = "mission", value = "std:mp_bravo" }, new AliasListing() { name = "carbon", value = "std:mp_carbon" }, new AliasListing() { name = "dome", value = "std:mp_dome" }, new AliasListing() { name = "downturn", value = "std:mp_exchange" }, new AliasListing() { name = "hardhat", value = "std:mp_hardhat" }, new AliasListing() { name = "interchange", value = "std:mp_interchange" }, new AliasListing() { name = "fallen", value = "std:mp_lambeth" }, new AliasListing() { name = "bakaara", value = "std:mp_mogadishu" }, new AliasListing() { name = "resistance", value = "std:mp_paris" }, new AliasListing() { name = "arkaden", value = "std:mp_plaza2" }, new AliasListing() { name = "outpost", value = "std:mp_radar" }, new AliasListing() { name = "seatown", value = "std:mp_seatown" }, new AliasListing() { name = "underground", value = "std:mp_underground" }, new AliasListing() { name = "village", value = "std:mp_village" },
// DLC maps new AliasListing() { name = "aground", value = "dlc:mp_aground_ss" }, new AliasListing() { name = "blackbox", value = "dlc:mp_morningwood" }, new AliasListing() { name = "boardwalk", value = "dlc:mp_Boardwalk" }, new AliasListing() { name = "decommission", value = "dlc:mp_Shipbreaker" }, new AliasListing() { name = "erosion", value = "dlc:mp_courtyard_ss" }, new AliasListing() { name = "foundation", value = "dlc:mp_Foundation" }, new AliasListing() { name = "getaway", value = "dlc:mp_hillside_ss" }, new AliasListing() { name = "gulch", value = "dlc:mp_gulch" }, new AliasListing() { name = "liberation", value = "dlc:mp_park" }, new AliasListing() { name = "lookout", value = "dlc:mp_restrepo_ss" }, new AliasListing() { name = "terminal", value = "dlc:mp_terminal_cls" }, new AliasListing() { name = "oasis", value = "dlc:mp_Qadeem" }, new AliasListing() { name = "offshore", value = "dlc:mp_roughneck" }, new AliasListing() { name = "overwatch", value = "dlc:mp_overwatch" }, new AliasListing() { name = "parish", value = "dlc:mp_NOLA" }, new AliasListing() { name = "piazza", value = "dlc:mp_italy" }, new AliasListing() { name = "sanctuary", value = "dlc:mp_meteora" }, new AliasListing() { name = "uturn", value = "dlc:mp_burn_ss" }, new AliasListing() { name = "intersection", value = "dlc:mp_crosswalk_ss" }, new AliasListing() { name = "vortex", value = "dlc:mp_six_ss" },
});
// Get and set all the directories in the zone folder string[] zoneDirectories = Directory.GetDirectories("zone"); List<string> directories = new List<string>();
foreach (string directory in zoneDirectories) { if (!directory.Contains("dlc")) directories.Add(directory); }
aliases.Add("zones", directories); }
/// <summary> /// Listens for when a client types in the chat, currently it listens for "!gametype" and "!gt" /// which are two pre-defined chat commands that can be assigned using the permissions plugin /// otherwise everyone will be able to use them. /// </summary> /// <param name="Message"></param> /// <param name="Client"></param> /// <returns></returns> public override ChatType OnSay(string Message, ServerClient Client) { if (Message.StartsWith("!gametype") || Message.StartsWith("!gt")) { string[] split = Message.Split(' ');
// Do we have enough arguments? if (split.Length < 3) { TellClient(Client.ClientNum, "^1Usage: ^7!" + split[0] + " <map name> <dsr name>", true); return ChatType.ChatNone; }
// Set the map name and game type mapName = split[1].ToLower(); gameType = split[2];
// Are the required arguments empty? if (string.IsNullOrEmpty(mapName) || string.IsNullOrEmpty(gameType)) { TellClient(Client.ClientNum, (string.IsNullOrEmpty(mapName) ? "^1Enter a map name" : "^1Enter a game type DSR name"), true); return ChatType.ChatNone; }
// Sort through all the maps specified in the alias list and determine if the map name // the user has entered matches something in that list setMapNameAndIsDLC();
// Check if the specified map exists on the server and also check if the game type given // is on that exists within the admin folder bool isMapValid = checkIfTheMapExists(); bool isGameTypeValid = File.Exists(@"admin\" + gameType + ".dsr");
// Check if the custom playlist file we created still exists, if it does we need to // delete it off the server so the normal playlist can continue to work after the map // has been changed if (File.Exists(@"admin\gametypechanger.dspl")) { File.Delete(@"admin\gametypechanger.dspl"); }
// Create the new playlist file that we can use to force the game type createDSPLFileAndMessageTheAdmins();
return ChatType.ChatNone; }
return ChatType.ChatContinue; }
/// <summary> /// When the map changes the custom DSPL file we set will take control of the map rotation so we /// need to switch it back to the original DSPL file. /// /// There is a downside to this which is that we have to incur another map rotation call which now /// increments the total to "2" rotations. /// /// Resets the variables that may still have values from the last change. /// </summary> public override void OnMapChange() { isDLC = false; mapName = string.Empty; gameType = string.Empty;
/// <summary> /// Loops through all the pre-defined maps that were constructed while the server was connecting to /// the server and tries to determine which map the user has chosen using the switch game type commands /// </summary> private void setMapNameAndIsDLC() { foreach (AliasListing map in aliases["maps"]) { string[] mapDetails = map.value.Split(':');
// Check if the given map name matches the current map name if (mapName == map.name || mapName == mapDetails[1]) { mapName = mapDetails[1]; isDLC = (mapDetails[0] == "dlc"); break; } } }
/// <summary> /// Checks if the given map exists on the server using the list of directories that we discovered /// in the zone folder earlier. /// </summary> /// <returns></returns> private bool checkIfTheMapExists() { if ((isDLC && File.Exists(@"zone\dlc\" + mapName + ".ff")) || !isDLC) { if (!isDLC) { foreach (string directory in aliases["zones"]) { if (File.Exists(directory + @"\" + mapName + ".ff")) return true; } } else { return true; } }
return false; }
/// <summary> /// It also create the custom DSPL file needed to set the user selected map and game type set via /// the commands. /// /// Lets all the admins on the server know the map was just changed using "!gametype" or "!gt" and /// what game type was loaded during the change. /// </summary> private void createDSPLFileAndMessageTheAdmins() { using (StreamWriter file = new StreamWriter(@"admin\gametypechanger.dspl", true)) { file.WriteLine(string.Format("{0},{1},1", mapName, gameType));
// Issue the server command to change the map ServerCommand("sv_maprotation gametypechanger"); ServerCommand("start_map_rotate");
// Display a server message to let the user know the map and game type has changed. Admins ONLY! string adminXUIDs = GetServerCFG("Permission", "Admin_xuids", ""); List<ServerClient> clients = GetClients();
if (!string.IsNullOrEmpty(adminXUIDs)) { foreach (ServerClient client in clients) { if (adminXUIDs.Contains(client.XUID)) TellClient(client.ClientNum, string.Format("^5Map changed to ^7{0} ^5using ^7{1} as the game type", mapName, gameType), true); } } } } }
/// <summary> /// A re-usable structure array that can be used for map aliases etc... /// </summary> public struct AliasListing { public string name, value; } }