/// <summary> Adds a new rank to the list. Checks for duplicates. </summary> public static void AddRank(Rank rank) { if (rank == null) { throw new ArgumentNullException("rank"); } if (PlayerDB.IsLoaded) { throw new InvalidOperationException("You may not add ranks after PlayerDB has already been loaded."); } // check for duplicate rank names if (RanksByName.ContainsKey(rank.Name.ToLower())) { throw new RankDefinitionException("Duplicate definition for rank \"{0}\" (by Name) was ignored.", rank.Name); } if (RanksByID.ContainsKey(rank.ID)) { throw new RankDefinitionException("Duplicate definition for rank \"{0}\" (by ID) was ignored.", rank.Name); } Ranks.Add(rank); RanksByName[rank.Name.ToLower()] = rank; RanksByFullName[rank.GetFullName()] = rank; RanksByID[rank.ID] = rank; RebuildIndex(); }
/// <summary> Adds a new rank to the list at the desired position in the hierarchy. Checks for duplicates. </summary> /// <param name="newRank"> Rank to add to the list. </param> /// <param name="desiredIndex"> Desired rank index (zero-based). </param> /// <exception cref="ArgumentNullException"> If rank is null. </exception> /// <exception cref="InvalidOperationException"> If PlayerDB is already loaded. </exception> /// <exception cref="RankDefinitionException"> If a rank with this name or ID is already defined. </exception> public static void AddRank([NotNull] Rank newRank, int desiredIndex) { if (desiredIndex < 0 || desiredIndex > Ranks.Count) { throw new ArgumentOutOfRangeException("desiredIndex"); } if (newRank == null) { throw new ArgumentNullException("newRank"); } CheckIfPlayerDBLoaded(); // check for duplicate rank names if (RanksByName.ContainsKey(newRank.Name.ToLower())) { throw new RankDefinitionException(newRank.Name, "Duplicate definition for rank \"{0}\" (by Name) was ignored.", newRank.Name); } if (RanksByID.ContainsKey(newRank.ID)) { throw new RankDefinitionException(newRank.Name, "Duplicate definition for rank \"{0}\" (by ID) was ignored.", newRank.Name); } Ranks.Insert(desiredIndex, newRank); RanksByName[newRank.Name.ToLower()] = newRank; RanksByFullName[newRank.FullName] = newRank; RanksByID[newRank.ID] = newRank; RebuildIndex(); }
/// <summary> Parses serialized rank. Accepts either the "name" or "name#ID" format. /// Uses legacy rank mapping table for unrecognized ranks. Does not autocomple. </summary> /// <param name="name"> Full rank name </param> /// <returns> If name could be parsed, returns the corresponding Rank object. Otherwise returns null. </returns> public static Rank ParseRank(string name) { if (name == null) { return(null); } if (RanksByFullName.ContainsKey(name)) { return(RanksByFullName[name]); } if (name.Contains("#")) { // new format string id = name.Substring(name.IndexOf("#") + 1); if (RanksByID.ContainsKey(id)) { // current class return(RanksByID[id]); } else { // unknown class int tries = 0; while (LegacyRankMapping.ContainsKey(id)) { id = LegacyRankMapping[id]; if (RanksByID.ContainsKey(id)) { return(RanksByID[id]); } // avoid infinite loops due to recursive definitions tries++; if (tries > 100) { throw new RankDefinitionException("Recursive legacy rank definition"); } } // try to fall back to name-only name = name.Substring(0, name.IndexOf('#')).ToLower(); return(RanksByName.ContainsKey(name) ? RanksByName[name] : null); } } else if (RanksByName.ContainsKey(name.ToLower())) { // old format return(RanksByName[name.ToLower()]); // LEGACY } else { // totally unknown rank return(null); } }