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:

function partialMatchUser(usern)
    local exact = game.Players:FindFirstChild(usern)
    if (exact ~= nil) then --If you put in a exact name, it should get the exact player every time
        return exact
    end
    --Do matching, no exact match
    local users = game.Players:GetChildren()
    local matches = {}
    for i = 1, #users do
        local unmLower = users[i].Name:lower()
        if (users[i].ClassName == "Player") and (string.sub(unmLower, 1, usern:lower()) == unmLower) then
            matches.insert(matches, users[i])
        end
    end
    if #matches == 1 then
        return matches[1]
    end
    --Returns nil if no matches or ambiguous
end
Log in to vote
-3
Answered by
nate890 495 Moderation Voter
11 years ago
local command = "/kill flub"

local names = {"flooby", "flubby", "bubs"}

command:lower()

for _, s in pairs(names) do
    local name = s:lower()
    print(name:sub(1, #command - #("/kill ")) == command:sub(1 + #("/kill "), #command))
end

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,

local command = "/kill flub"

command:lower()

local found = {}
for _, player in pairs(game.Players:GetPlayers()) do
    local name = player.Name:lower()
    if name:sub(1, #command - #("/kill ")) == command:sub(1 + #("/kill "), #command) then
        table.insert(found, player)
    end
end

if #found == 1 then
    pcall(function() --Because I'm lazy
        found[1].Character:BreakJoints()
    end)
else
    print(#found == 0 and "No one found" or "Ambiguous")
end
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