Tayla Wilson
Tayla Wilson

Reputation: 494

C# Find specific text in listbox

I'm creating an application that runs a Java server in the background and outputs to a console listbox with each new line. However, I want to be able to create a timer for example that constantly reads the console listbox for certain pre-determined things but not specific.

For example, if the server outputs "[17:32:50 INFO]: Matt[127.0.0.1]logged in with entity ID 233 at ([world]co-ordinates in world)" and adds it to the console listbox as an item, I want to be able to just grab the "Matt" part and add it to a list of players currently online in a players listbox. The "entity ID" and "co-ordinates in world" will be different every time so cannot be determined.

As well as this I'd like to do the same thing when the player disconnects, the console listbox will add an item that will say "Matt left the game" and I'd need it to be able to search the players listbox for "Matt" and remove that item.

I'm wondering if this is possible, apologies if this isn't very clear!

Upvotes: 2

Views: 1679

Answers (3)

Calcolat
Calcolat

Reputation: 898

Edit:

If you want to get the players name and then either add or remove it from an "Online Players" listbox, you can use Substring() to search inside a string starting at x index and selecting for y length.

Here's an updated version for you that should work with the new format:

private void cmdLogin_Click(object sender, EventArgs e)
{
    // Add example logins
    lstConsoleOutput.Items.Add("[17:32:50 INFO]: Amy[/127.0.0.1:12345]logged in with entity ID 233 at ([world]co-ordinates in world)");
    lstConsoleOutput.Items.Add("[18:42:51 INFO]: Dan[/255.255.255.255:23451]logged in with entity ID 233 at ([world]co-ordinates in world)");
    lstConsoleOutput.Items.Add("[19:33:27 INFO]: Matt[/1.1.1.1:34512]logged in with entity ID 233 at ([world]co-ordinates in world)");
    lstConsoleOutput.Items.Add("[02:17:03 INFO]: Some Really Long Screen Name[/292.192.92.2:45123]logged in with entity ID 233 at ([world]co-ordinates in world)");
    lstConsoleOutput.Items.Add("[09:05:55 INFO]: ABC $!@#$ 12341234[/127.0.0.1:51234]logged in with entity ID 233 at ([world]co-ordinates in world)");

    AnalyzeConsoleOutput(lstConsoleOutput, lstOnlinePlayers);
}

private void cmdLogout_Click(object sender, EventArgs e)
{
    // Add example logouts
    lstConsoleOutput.Items.Add("[22:12:12 INFO]: Amy left the game");
    lstConsoleOutput.Items.Add("[23:44:15 INFO]: Matt left the game");
    lstConsoleOutput.Items.Add("[24:00:00 INFO]: ABC $!@#$ 12341234 left the game");

    AnalyzeConsoleOutput(lstConsoleOutput, lstOnlinePlayers);
}

private void AnalyzeConsoleOutput(ListBox listboxToAnalyze, ListBox onlinePlayersListbox)
{
    const string LoginIdentifier = "]logged in with entity";
    const string LogoutIdentifer = " left the game";
    string playerName;

    foreach (var item in listboxToAnalyze.Items)
    {
        // Check if a player has logged in and add them to the players list box
        if (item.ToString().Contains(LoginIdentifier))
        {
            int startOfPlayerNameIndex = item.ToString().IndexOf("]: ") + 3;
            int lengthOfPlayerName = item.ToString().IndexOf('[', item.ToString().IndexOf('[') + 1) - startOfPlayerNameIndex;

            playerName = item.ToString().Substring(startOfPlayerNameIndex, lengthOfPlayerName);

            if (!onlinePlayersListbox.Items.Contains(playerName))
            {
                onlinePlayersListbox.Items.Add(playerName);
            }
        }

        // Check if a player has logged out and remove them from the players list box
        if (item.ToString().Contains(LogoutIdentifer))
        {
            int startOfPlayerNameIndex = item.ToString().IndexOf("]: ") + 3;
            int lengthOfPlayerName = item.ToString().IndexOf(LogoutIdentifer, 0) - startOfPlayerNameIndex;

            playerName = item.ToString().Substring(startOfPlayerNameIndex, lengthOfPlayerName);

            if (onlinePlayersListbox.Items.Contains(playerName))
            {
                onlinePlayersListbox.Items.Remove(playerName);
            }
        }
    }
}

This now uses 2 variables to set the start index of the players name and another to set the number of characters to count. By doing it this way, if the format changes in the future you only need to update these things and everything else should still work. I've also kept the 2 consts for LoginIdentifier and LogoutIdentifier that you can change if needed.

This should also work with or without a / in the IP address. So either "[111" or "[/111" should still work fine with this. Hope this helps.

Upvotes: 1

user3016120
user3016120

Reputation: 26

foreach (var listBoxItem in listBox1.Items)
{
    // use the currently iterated list box item

    if (listBoxItem.ToString().Contains("logged"))
    {
        // Do your stuff here
    }
}

Upvotes: 1

Farcrada
Farcrada

Reputation: 75

You could loop through the listbox's items and search for objects that are split and pick the "left" side of the split.

string CheckForMatchNames()
{
    foreach(string item in listbox.items)
        for (int i = 0; i < preDeterminedStringArrayThatMustMatchSomething.Length; i++)
            if (item.Split('[')[0] == preDeterminedStringArrayThatMatchesSomething[i])
                return preDeterminedStringArrayThatMustMatchSomething[i];
    return "none";
}

Upvotes: 0

Related Questions