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

Im making a player-finder for shortened names in my admin commands. Why isn't it working?

Asked by
Poine 30
8 years ago
function find(short)
    local plyr = "invalid"
    for _,v in pairs(game.Players:GetPlayers()) do
        local length = string.len(v.Name)
        if string.lower(string.sub(v.Name,1,length)) == string.sub(short,1,length) then
            plyr = v.Name
        end
    end
    return plyr
end

It always returns null. No errors.

2 answers

Log in to vote
1
Answered by
M39a9am3R 3210 Moderation Voter Community Moderator
8 years ago

Problem

What you're trying to do with your script is compare the length of a user's name to an incomplete string of the target. What I am saying is when you target a person, let's say Person299, and you type in pers then the script reads it as you're comparing 'person299' == 'pers '. The script is having to compare the name to a partial name with spaces.


Solution

Do the opposite. Essentially what you want to do is compare the partial name of input to the partial name of the physical player. Also, you can use the functions :sub() and :len() on a string and you will get the exact same results as string.sub() and string.len()


Final Script

By the way, I modified the function to return the physical player if existent that way you may find it easier. You would need to show a modified script if you want to target multiple players in a single string. However, if you do not like this change I will leave a fixed version of the original for use.

function GetPlayer(PartialName) --GetPlayer should be called when you want to get the player with the partial name.
    for _,v in pairs(game:GetService('Players'):GetPlayers()) do --For everything in Players Service do...
        if v.Name:lower():sub(1,PartialName:len()) == PartialName:lower() then --If the name matches the partial, we have a winner.
            return v --The script will return the player.
        end
    end
    return nil --Apparently at this point, the intended player does not exist.
end

Original script:

function find(short)
    local plyr = "invalid"
    for _,v in pairs(game.Players:GetPlayers()) do
        if string.lower(string.sub(v.Name,1,length)) == string.sub(short,1,length) then
            plyr = v.Name
        end
    end
    return plyr
end

Hopefully this answered your question. If so, do not forget to hit the accept answer button. If you have any questions feel free to comment below.
Ad
Log in to vote
1
Answered by 8 years ago

Personal preference

Honestly, I find using the string library a bit easier in most cases when using them as methods on a string value. To me, it just looks cleaner (in most cases), same with the # operator instead of using string.len. But this is just me, obviously you can use string manipulation however you want and it really doesn't matter.

The problem

Anyway, the solution to your problem is actually quite simple. In your first if statement comparison, you're lowering the text of the player's name, and comparing that to an unknown case variation as your short variable. We can fix this by simply lowering that string as well. Here would be my revision of your code:

local Players = game:GetService'Players' -- Maybe have this somewhere?

local function ShortName(stub)
    for i,v in next, Players:GetPlayers() do -- I just prefer using next. Again, just a preference.

        -- If player name's name subbed 1 through #stub is equal to stub converted to lower case characters, then ...
        if v.Name:lower():sub(1,#stub) == stub:lower() then
            return v.Name -- return player's found name
        end
    end
end

print(ShortName("Pla")) -- Maybe try this in studio

Anyway, hope that helped. Let me know if you have any questions.

Answer this question