Skip to content

Commit

Permalink
Merge pull request #44 from TobiasDeBruijn/direct-command
Browse files Browse the repository at this point in the history
Direct command
  • Loading branch information
TobiasDeBruijn authored Sep 28, 2022
2 parents 77e8a41 + b517892 commit a1ba5f9
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 20 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,9 @@ releases
bin/

actions/

# IntelliJ
.idea/

# Vscode
.vscode/
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
Minecraft Spigot

SkinFixer aims to make skins possible for Offline-mode servers, and allow for users to change their skin in-game.

SkinFixer also works with Discord. You can upload your skin to a designated Discord channel, and get a code.

## Commands
Expand All @@ -12,11 +11,16 @@ SkinFixer also works with Discord. You can upload your skin to a designated Disc
- `/skin reload` Reload SkinFixer's configuration
- `/skin reset` Reset your skin back to defaults. This will remove it from the local storage. Relog to see the effects
- `/skin version` Perform an update check
- `/skin direct <url>` Fetches and immediately applies skin from URL. Useful for automated server-side skin management when reading a code from chat isn't feasible.


- `/setskin <url>` Same as `/skin direct <url>`

## Permissions
- `skinfixer.get` Allows the use of the `get` subcommand. Default: ALL
- `skinfixer.reload` Allows the use of the `reload` subcommand. Default: OP
- `skinfixer.reset` Allows the use of the `reset` subcommand. Default: ALL
- `skinfixer.set` Allows the use of the `set` subcommand. Default: ALL
- `skinfixer.set` Allows the use of the `set` and `direct` subcommand (and thus also `/setskin`). Default: ALL
- `skinfixer.version` Allows the use of the `version` subcommand. Default: OP

## Features
Expand Down Expand Up @@ -76,7 +80,7 @@ sendMetrics: true
```
## APIs
SkinFixer relies only on the [SkinFixer API](https://github.com/TheDutchMC/SkinFixer-API). This API relies on two other APIs under the hood
SkinFixer relies only on the [SkinFixer API](https://github.com/TobiasDeBruijn/SkinFixer-API). This API relies on two other APIs under the hood
- Mojang API
- [MineSkin API](https://github.com/MineSkin/api.mineskin.org)
Expand All @@ -87,7 +91,7 @@ The Mojang API was moved from being on the plugin side to being on the API side
Please try to follow my codestyle, I don't yet follow any guideline myself.
## Issues
Issues can be reported [here](https://github.com/TheDutchMC/SkinFixer/issues)
Issues can be reported [here](https://github.com/TobiasDeBruijn/SkinFixer/issues)
## Building
Refer to [this document](BUILDING.md)
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
pluginVersion = 1.7.8
pluginVersion = 1.7.7
2 changes: 1 addition & 1 deletion src/main/java/dev/array21/skinfixer/SkinFixer.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public void onEnable() {
PLUGIN_VERSION = this.getDescription().getVersion();
LOGGER = this.getLogger();

SkinFixer.logInfo("Welcome to SkinFixer version " + PLUGIN_VERSION + " by TheDutchMC!");
SkinFixer.logInfo("Welcome to SkinFixer version " + PLUGIN_VERSION + " by TheDutchMC! (Extra /direct Command added by Sw3d15h_F1s4)");

//Read the configuration
this.configHandler = new ConfigHandler(this);
Expand Down
45 changes: 34 additions & 11 deletions src/main/java/dev/array21/skinfixer/commands/CommandHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.bukkit.command.TabCompleter;

import dev.array21.skinfixer.SkinFixer;
import dev.array21.skinfixer.commands.subcommands.DirectCommand;
import dev.array21.skinfixer.commands.subcommands.GetCommand;
import dev.array21.skinfixer.commands.subcommands.HelpCommand;
import dev.array21.skinfixer.commands.subcommands.ReloadCommand;
Expand All @@ -36,6 +37,7 @@ public CommandHandler(SkinFixer plugin) {
registerCommand(new SetCommand());
registerCommand(new GetCommand());
registerCommand(new ReloadCommand());
registerCommand(new DirectCommand());
}

/**
Expand All @@ -45,15 +47,38 @@ public CommandHandler(SkinFixer plugin) {
*/
private void registerCommand(Subcommand cmd) throws IllegalArgumentException {
if(!cmd.getClass().isAnnotationPresent(CommandInfo.class)) {
throw new IllegalArgumentException("Provided Subcommand is not annotateddw with CommandInfo");
throw new IllegalArgumentException("Provided Subcommand is not annotated with CommandInfo");
}

CommandInfo info = cmd.getClass().getAnnotation(CommandInfo.class);
if(this.subcommands.containsKey(info.name())) {
throw new IllegalStateException(String.format("Command with name '%s' is already registered.", info.name()));
}

this.subcommands.put(info.name(), cmd);
this.helpMessages.put(info.name(), info.description());
this.subcommandPermissions.put(cmd, info.permission());

if(!info.globalCommand().equals("")) {
if(this.plugin.getCommand(info.globalCommand()) == null) {
throw new IllegalStateException(String.format("Subcommand '%s' called for '%s' to be registered as a global command, however the command is not registered in 'plugin.yml'", info.name(), info.globalCommand()));
}

this.plugin.getCommand(info.globalCommand()).setExecutor((sender, command, label, args) -> CommandHandler.this.onCommandHandler(sender, args, cmd));

this.plugin.getCommand(info.globalCommand()).setTabCompleter((sender, command, alias, args) -> CommandHandler.this.onTabCompleteHandler(sender, args, cmd));
}
}

private boolean onCommandHandler(CommandSender sender, String[] args, Subcommand subcommand) {
if(!this.subcommandPermissions.get(subcommand).isEmpty() && !sender.hasPermission(this.subcommandPermissions.get(subcommand))) {
sender.sendMessage(SkinFixer.getPrefix() + ChatColor.GOLD + LangHandler.model.commandNoPermission);
return true;
}

subcommand.onSubcommand(this.plugin, sender, Arrays.copyOfRange(args, 1, args.length));
return true;
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if(args.length == 0) {
Expand All @@ -67,15 +92,13 @@ public boolean onCommand(CommandSender sender, Command command, String label, St
return true;
}

if(!this.subcommandPermissions.get(exec).isEmpty() && !sender.hasPermission(this.subcommandPermissions.get(exec))) {
sender.sendMessage(SkinFixer.getPrefix() + ChatColor.GOLD + LangHandler.model.commandNoPermission);
return true;
}

exec.onSubcommand(this.plugin, sender, Arrays.copyOfRange(args, 1, args.length));
return true;
return this.onCommandHandler(sender, args, exec);
}


private List<String> onTabCompleteHandler(CommandSender sender, String[] args, Subcommand subcommand) {
return Arrays.asList(subcommand.onSubcommandComplete(this.plugin, sender, Arrays.copyOfRange(args, 1, args.length)));
}

@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
if(args.length == 1) {
Expand All @@ -86,7 +109,7 @@ public List<String> onTabComplete(CommandSender sender, Command command, String
if(exec == null) {
return null;
}
return Arrays.asList(exec.onSubcommandComplete(this.plugin, sender, Arrays.copyOfRange(args, 1, args.length)));

return this.onTabCompleteHandler(sender, args, exec);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@
public String name();
public String description();
public String permission() default "";
public String globalCommand() default "";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package dev.array21.skinfixer.commands.subcommands;

import java.util.UUID;

import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;

import dev.array21.skinfixer.SkinChangeHandler;
import dev.array21.skinfixer.SkinFixer;
import dev.array21.skinfixer.commands.CommandInfo;
import dev.array21.skinfixer.commands.Subcommand;
import dev.array21.skinfixer.common.AddNewSkin;
import dev.array21.skinfixer.language.LangHandler;
import net.md_5.bungee.api.ChatColor;

@CommandInfo(name = "direct", description = "Fetches a skin code and immediately applies skin to sender. URL must be Skin image. Only accepts URLs.", permission = "skinfixer.set", globalCommand = "setskin")
public class DirectCommand implements Subcommand {

@Override
public void onSubcommand(SkinFixer plugin, CommandSender sender, String[] args) {
if (!(sender instanceof Player)) {
sender.sendMessage(SkinFixer.getPrefix() + ChatColor.RED + LangHandler.model.commandPlayerOnly);
return;
}

// User must provide a URL
if (args.length == 0) {
sender.sendMessage(ChatColor.RED + LangHandler.model.missingUrlArgument);
return;
}

// Check that the user actually supplied a URL
if (!(args[0].contains("https://") || args[0].contains("http://"))) {
sender.sendMessage(ChatColor.RED + LangHandler.model.invalidUrlArguemnt);
}

// Filter off the query parameters
int indexOfQuery = args[0].indexOf('?');
int endIndex = indexOfQuery > 0 ? indexOfQuery : args[0].length();
String url = args[0].substring(0, endIndex);

// Check if the skin is a slim model
boolean slim = args.length >= 2 && args[1].equalsIgnoreCase("true");

// Apply the skin
new SkinChangeHandler(plugin).changeSkinJson(url, ((Player) sender).getUniqueId(), null, slim, false, false);
}

@Override
public String[] onSubcommandComplete(SkinFixer plugin, CommandSender sender, String[] args) {
return new String[0];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,10 @@ public class LanguageModel {

@Required
public String reloadSuccessful;

@Required
public String missingUrlArgument;

@Required
public String invalidUrlArguemnt;
}
7 changes: 5 additions & 2 deletions src/main/resources/en.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
skinFetching: Fetching skin value and signature...
skinApplyFailed: Something went wrong applying your skin %ERROR%
skinApplying: Applying skin...
skinApplied: Done.
skinApplied: Done. Other players can now see your skin.

commandPlayerOnly: This command is for players only!
commandNoPermission: You don't have permission to use this command!
Expand All @@ -22,4 +22,7 @@ discordSetSkin: You can set this as your skin in-game using /skin set %CODE%
skinReset: Your skin has been reset! SkinFixer will fetch a new skin, if it is available, the next time you join the game!

unknownCommand: The command provided was not recognized. Use /skin help to see a list of available commands.
reloadSuccessful: SkinFixer was reloaded successfully.
reloadSuccessful: SkinFixer was reloaded successfully.

missingUrlArgument: You must provide a URL from where to load the new skin. The URL must point directly to an image file
invalidUrlArgument: The provided URL is not valid. It must start wih http:// or https://
4 changes: 3 additions & 1 deletion src/main/resources/plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ api-version: 1.16
commands:
skin:
description: SkinFixer's main command
setskin:
description: Set a skin directly from a URL

permissions:
skinfixer.get:
Expand All @@ -17,4 +19,4 @@ permissions:
skinfixer.set:
default: true
skinfixer.version:
default: op
default: op

0 comments on commit a1ba5f9

Please sign in to comment.