commands icon indicating copy to clipboard operation
commands copied to clipboard

Resolved Player is always null

Open Silthus opened this issue 3 years ago • 3 comments

Thanks for the awesome framework. I have a question about the context resolver and how it treats players? I have the problem that my resolved player is always null and I am unable to find any documentation on how exactly context resolvers work.

I have the following command with two custom resolvers SkilledPlayer and Skill:

    @Subcommand("add")
    @CommandCompletion("@players @skills")
    @Description("{@@rcskills.add-cmd.desc}")
    @CommandPermission("rcskills.admin.skill.add")
    public void addSkill(SkilledPlayer skilledPlayer, Skill skill) {

        skilledPlayer.addSkill(skill);
        getCurrentCommandIssuer().sendMessage("{@@rcskills.add-cmd.info}");
    }
        commandManager.getCommandContexts().registerContext(Skill.class, context -> {
            Optional<Skill> skill = getSkillManager().findSkillByNameOrId(context.popFirstArg());
            if (skill.isEmpty()) {
                throw new InvalidCommandArgument("{@@rcskills.resolver.skill.error}");
            }
            return skill.get();
        });
        commandManager.getCommandContexts().registerContext(net.silthus.skills.SkilledPlayer.class, context -> {
            Player player = (Player) context.getResolvedArg(Player.class);
            return skillManager.getPlayer(player);
        });

The player I get from context.getResolvedArg(Player.class) is always null and the context.popFirstArg()` also sometimes returns null and I do not know why.

The executed command is /rcs add Silthus test where Silthus is the player name and test the skill identifier.

What do I need to change for my use case?

Silthus avatar Nov 14 '20 01:11 Silthus

IIRC popFirstArg can only return null if you annotate the parameter with @Optional. Try this:

Player player = Bukkit.getPlayerExact(context.popFirstArg());
// if player == null throw exception
return skillManager.getPlayer(player);

RoinujNosde avatar Nov 14 '20 01:11 RoinujNosde

Thanks for the reply I will try that. But what does context.getResolvedArg(Player.class); do then? I assumed that that will resolve the Player from the given String.

Another question? How can I use placeholders inside my language translations? e.g.: I have my InvalidCommandArgument("{@@rcskills.resolver.skill.error}")" exception and want to show the name of the skill that was passed as the argument? Can I use something like this The skill %skillname was not found? But how would I pass the %skill` argument to the translation?

Silthus avatar Nov 14 '20 10:11 Silthus

But what does context.getResolvedArg(Player.class); do then? I assumed that that will resolve the Player from the given String.

It would return a Player if you had Player in the command's parameters.

For the placeholders question see this example: https://github.com/aikar/commands/blob/a26babd6d8261de7ccb321aa63115b4d359139ec/core/src/main/java/co/aikar/commands/CommandContexts.java#L54

RoinujNosde avatar Nov 14 '20 10:11 RoinujNosde