Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

How would you find and return a player with only part of their name? [closed]

Asked by 11 years ago

For example, typing /kill su would kill the user Superburke.

Locked by FearMeIAmLag

This question has been locked to preserve its current state and prevent spam and unwanted comments and answers.

Why was this question closed?

3 answers

Log in to vote
0
Answered by 11 years ago

The find function of the string library can be used to check if a string contains another string and you can make the check not case sensitive by using the lower case versions of both strings.

To check if the string source is part of the name of a player player, you can use player.Name:lower():find(source:lower(), 1, true). This will evaluate to true if the lower case name of the player contains the lower case string. The true in the last argument is there in order to tell the find function that it should not use string patterns and the 1 preceding it is there because the initial position must be given when a plain match is performed (which is the case here because the last argument is true).

Ad
Log in to vote
-2
Answered by
Bubby4j 231 Moderation Voter
11 years ago

The other questions don't deal with whether there are multiple matches. Usually if you want to run a command, say "/ban User", then with their answers it'd ban any user in the game that had a name such as User, Username, User1, User2, etc.

You need to detect if it's ambiguous.

Here's a nifty little helper function I wrote a while ago, ported to lua:

01function partialMatchUser(usern)
02    local exact = game.Players:FindFirstChild(usern)
03    if (exact ~= nil) then --If you put in a exact name, it should get the exact player every time
04        return exact
05    end
06    --Do matching, no exact match
07    local users = game.Players:GetChildren()
08    local matches = {}
09    for i = 1, #users do
10        local unmLower = users[i].Name:lower()
11        if (users[i].ClassName == "Player") and (string.sub(unmLower, 1, usern:lower()) == unmLower) then
12            matches.insert(matches, users[i])
13        end
14    end
15    if #matches == 1 then
16        return matches[1]
17    end
18    --Returns nil if no matches or ambiguous
19end
Log in to vote
-3
Answered by
nate890 495 Moderation Voter
11 years ago
01local command = "/kill flub"
02 
03local names = {"flooby", "flubby", "bubs"}
04 
05command:lower()
06 
07for _, s in pairs(names) do
08    local name = s:lower()
09    print(name:sub(1, #command - #("/kill ")) == command:sub(1 + #("/kill "), #command))
10end

I'm too lazy to explain how that works fully but it's pretty self explanatory and I'm pretty sure it's what you're looking for. If the characters after the "/kill " command match the characters of the string being checked in the names table (starting from the first character of the string) true will be outputted.

If you wanted to make that more "roblox" friendly, you'd do something like this,

01local command = "/kill flub"
02 
03command:lower()
04 
05local found = {}
06for _, player in pairs(game.Players:GetPlayers()) do
07    local name = player.Name:lower()
08    if name:sub(1, #command - #("/kill ")) == command:sub(1 + #("/kill "), #command) then
09        table.insert(found, player)
10    end
11end
12 
13if #found == 1 then
14    pcall(function() --Because I'm lazy
15        found[1].Character:BreakJoints()
16    end)
17else
18    print(#found == 0 and "No one found" or "Ambiguous")
19end
0
If there's 2 players in a game, Flub, and Flubby, it'll kill both of them at the same time. Not what you want usually. Bubby4j 231 — 11y
0
Edited according to Bubby4j's standards. nate890 495 — 11y