DisplayedName search engine

For all mod-related questions and custom code.
Post Reply
Jonty800
Offline
Posts: 280
Joined: August 21st, 2011, 6:31 am
Location: United Kingdom
Contact:

DisplayedName search engine

Post by Jonty800 »

Code: Select all

static readonly CommandDescriptor CdWhoIs = new CommandDescriptor
        {
            Name = "WhoIs", //you should change the command name, unless you remove /Whois from /Info
            Category = CommandCategory.Info,
            Permissions = new Permission[] { Permission.ViewOthersInfo },
            IsConsoleSafe = false, //I don't need console access for this, hasn't been tested for true
            Usage = "/Whois DisplayedName",
            Handler = WhoIsHandler
        };
        private static void WhoIsHandler(Player player, Command cmd)
        {
            string Name = cmd.Next(); //the desired displayedName
            if (string.IsNullOrEmpty(Name)) //check if null and print usage
            {
                CdWhoIs.PrintUsage(player);
                return;
            }
            Name = Color.StripColors(Name.ToLower()); //make the argument lowercase, and strip colors
//here we want a collection of players who HAVE a displayedName, 
//and the displayedName either contains the string in question (Name)
            PlayerInfo[] Names = PlayerDB.PlayerInfoList.Where(p => p.DisplayedName != null &&
                Color.StripColors(p.DisplayedName.ToLower()).Contains(Name))
                                         .ToArray();
            Array.Sort(Names, new PlayerInfoComparer(player));
            if (Names.Length < 1){ //if no results were found
                player.Message("&WNo results found with that DisplayedName");
                return;
            }
            if (Names.Length == 1){ //if one result was found
                player.Message("One player found with that DisplayedName: {0}", Names[0].Rank.Color + Names[0].Name); //display the 1 results name, coloured by rank color
                return;
            }
            if (Names.Length <= 30){
                MessageManyMatches(player, Names); //if all names fit onto a page, print all names found
            }else{ //else, use pagination to display the results
                int offset;
                if (!cmd.NextInt(out offset)) offset = 0;
                if (offset >= Names.Length)
                    offset = Math.Max(0, Names.Length - 30);
                PlayerInfo[] Part = Names.Skip(offset).Take(30).ToArray();
                MessageManyMatches(player, Part);
                if (offset + Part.Length < Names.Length){
                    player.Message("Showing {0}-{1} (out of {2}). Next: &H/Whois {3} {4}",
                                    offset + 1, offset + Part.Length, Names.Length,
                                    Name, offset + Part.Length);
                }else{
                    player.Message("Showing matches {0}-{1} (out of {2}).",
                                    offset + 1, offset + Part.Length, Names.Length);
                }
            }
        }

//simple static method to format the list of names[] and join them to a string for printing
        static void MessageManyMatches(Player player, PlayerInfo[] names)
        {
            if (names == null) throw new ArgumentNullException("names");

            string nameList = names.JoinToString(", ", p => p.Rank.Color + p.Name + "&S(" + p.ClassyName + "&S)");
            player.Message("More than one player matched with that DisplayedName: {0}",
                     nameList);
        }
Last edited by Jonty800 on September 14th, 2012, 4:51 pm, edited 2 times in total.
You cannot use certain BBCodes: [img].

User avatar
fragmer
fCraft Developer
Offline
Posts: 1386
Joined: May 21st, 2011, 10:53 pm

Re: DisplayedName search engine

Post by fragmer »

If you want to utilize same sorting order for the results that PlayerDB uses internally (by online status, then by rank, then by time-since-last-seen), save results to array and use following:

Code: Select all

Array.Sort( yourInfosArray, new PlayerInfoComparer( player ) )
(Player object is required as an argument to PlayerInfoComparer in order to treat hidden players as "offline" properly.)

I'd recommend using "Color.StripColors" on the given name as well. Just in case.

"p.DisplayedName.StartsWith" check is redundant, since "p.DisplayedName.Contains" also tests for the possibility.

Other than these little nitpicks, this is a very handy little method. I've been meaning to add something like this for a while.

Jonty800
Offline
Posts: 280
Joined: August 21st, 2011, 6:31 am
Location: United Kingdom
Contact:

Re: DisplayedName search engine

Post by Jonty800 »

Thanks for the suggestions :) Will add and update when I get time.
"p.DisplayedName.StartsWith" check is redundant, since "p.DisplayedName.Contains" also tests for the possibility.
Yeah, this was rather silly of me :P

Edit: Updated code

Edit edit: Do I need .Reverse() with the PlayerInfoComparer sorting?

Edit edit edit: Removed .Reverse()
You cannot use certain BBCodes: [img].

Post Reply