WHAT YOU WILL MAKE
/kit toolkit with parameter checking
A /kit command first checks the caller, permissions and parameters before putting items into the backpack. You'll take care of player, console, and full inventory situations at the same time, so failures are clearly responded to. Front backpack: Gradle project and Paper test server of Lesson 31. Copy the project to BlockAcademyL32, keep the build script, and change the project name in settings to BlockAcademyL32.
Before you start: It is recommended to complete Lesson 31 first
01 / 13
Before starting: first recognize the running position
The first 30 lessons lay the foundation for ordinary Java programs. At this stage, the code is connected to the Paper server: the Minecraft client is responsible for entering the world, the server loads the plug-in, and the events and commands hand over player actions to your methods.
This book uses JDK 21 and Paper 1.21.11, and the client version is also consistent. The latest version on the download page may have changed, select it by version number. This book uses normal plugin.yml and the Bukkit API; no claims are made to support Folia at this stage.
The short examples in the picture frame are partial fragments. Read the location description of this section first, and do not save each as a plug-in. The file name will be clearly given for the complete file; when the same file is divided into multiple segments, they will be connected by number, and the package name, import and outer class will only appear once.
- Prediction: Write success conditions and expected messages first.
- Run: After successful construction, install and restart on the dedicated local test server.
- Verification: Ordinary players, management identities and consoles take corresponding paths respectively.
02 / 13
First recognize who is giving the order
The villager entered the command to receive the tool kit at the console, but the program asked him for the backpack. The console has no hands and no hotbar. In the first level of the command, first identify the caller, then count the parameters, and finally open the recipe box.
Treat the command as a gated route: the backpack is modified only after the caller type, authority, number of parameters, and parameter content have all passed. Failure is also a process that requires a clear reply. Don’t let players only see silence.
- PlayerCan receive a backpack
- ConsoleObtained an explicit rejection
- Common rulesOnly change items after checking
Obtain players safely. See the instructions in this section for their positions.
if (!(sender instanceof Player player)) {
sender.sendMessage("Please collect the tool kit in the game");
return true;
}
player.sendMessage(Component.text("Backpack owner confirmed"));Wrong cast · Intentional error, predict first and then fix
Player player = (Player) sender; // Console execution will cause errors03 / 13
Count parameters first and then open the grid
When entering /kit miner, kit is the command name, and there is only miner in args; args[0] is not kit. When the player only types /kit, the array length is 0, and reading the 0th cell is out of bounds.
- Count parameters firstLength must be 1
- Read the 0th box againIt is a miner, not a kit
- Finally recognize the formulaUnknown options explicitly rejected
Before entering the next step along the arrow, the conditions of the previous step must be met; the rejected branch returns early.
Only accepts one parameter. See the description in this section for the position.
if (args.length != 1) {
player.sendMessage(Component.text("Usage: /kit miner or /kit builder"));
return true;
}Comparison that is not affected by system language · See the description in this section for the location
String name = args[0].toLowerCase(Locale.ROOT);| Enter | Length | Result |
|---|---|---|
| /kit | 0 | Show usage |
| /kit miner | 1 | Select miner package |
| /kit miner extra | 2 | Show usage |
| /kit wizard | 1 | Prompt unknown toolkit |
04 / 13
The command list and permissions must be matched
Create lesson32 package, the main class is called KitPlugin, replace plugin.yml in the resource directory. The exercise allows players to receive it by default, and the code still checks permissions to facilitate the withdrawal of a player's qualifications by the permission management system in the future.
- command kitList corresponds to getCommand
- Authority nodeCode checks before execution
- Default rulesThis chapter defaults to true
Complete plugin.yml of this lesson · Complete file
name: BlockAcademyL32
version: 1.0.0
main: de.teacherma.lesson32.KitPlugin
api-version: '1.21.11'
author: TeacherMa
website: https://www.teacher-ma.de
commands:
kit:
description: Get classroom tool kit
usage: /kit <miner|builder>
permissions:
blockacademy.kit:
default: truePre-execution check authority · See the description in this section for the location
if (!player.hasPermission("blockacademy.kit")) {
player.sendMessage(Component.text("You have not received the permission yet"));
return true;
}05 / 13
Where to go when the backpack is full of items?
addItem attempts to put the item into the backpack and returns the part that was not put in. The returned Map records the remaining items, and the key is the serial number of the input item, not the backpack slot. You can’t just say “received successfully” and forget about the remaining items.
- Try to enter the packageaddItem modifies backpack
- Get the remainderReturn the items in the Map
- Handle truthfullyDropped at feet and prompted
Send items and process the remaining items. See the description in this section for the location.
var leftovers = player.getInventory().addItem(
new ItemStack(Material.TORCH, 16));
for (ItemStack item : leftovers.values()) {
player.getWorld().dropItemNaturally(player.getLocation(), item);
}Feedback must conform to the results. See the description in this section for the location.
String message = leftovers.isEmpty()
? "Put all into backpack" : "The remaining items fell at your feet";
player.sendMessage(Component.text(message));06 / 13
Press Tab to give the player a hint
Command completion only recommends possible inputs, and parameters still need to be checked during actual execution. Otherwise, players can bypass rules that only exist in menus by manually entering a strange name.
- Completion promptOnly legal names are recommended
- Perform verificationManual input still needs to be checked
- Unknown prefixReturn empty list
Filter completion items from the list · See the description in this section for the location
String prefix = args[0].toLowerCase(Locale.ROOT);
return List.of("miner", "builder").stream()
.filter(name -> name.startsWith(prefix)).toList();Do not access parameters that do not exist. See the description in this section for the location.
if (args.length != 1) return List.of();
if (!sender.hasPermission("blockacademy.kit")) return List.of();| Current parameters | Recommend |
|---|---|
| Empty string | miner and builder |
| m | miner |
| b | builder |
| z | Empty list |
07 / 13
The tool kit formula is first written on paper
Today's challenge is two kits. First write down the recipe clearly, and then string together input, judgment, distribution and feedback. The practice version can be obtained repeatedly; the cooling function will be added after learning the 34th lesson.
- miner1 stone pickaxe and 16 torches
- builder32 wooden boards, 16 glass
- Unknown nameStop issuing after returning null
Use switch to select formula · See the description in this section for the location
ItemStack[] items = switch (name) {
case "miner" -> new ItemStack[] {
new ItemStack(Material.STONE_PICKAXE),
new ItemStack(Material.TORCH, 16)};
default -> null;
};| Toolkit | Item one | Item two |
|---|---|---|
| miner | 1 stone pick | 16 torches |
| builder | 32 oak planks | Glass 16 pieces |
08 / 13
Toolkit program first half
Create new src/main/java/de/teacherma/lesson32/KitPlugin.java. Copy this page first, then the next page immediately after; do not include package names, imports, or extra braces.
- A source documentThe front and rear parts are connected sequentially
- Check firstTypes, Permissions and Parameters
- After passingJust enter formula and distribution
KitPlugin Part 1 · This section 1/2, sequential connection
package de.teacherma.lesson32;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import net.kyori.adventure.text.Component;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
public final class KitPlugin extends JavaPlugin {
@Override
public void onEnable() {
var kit = Objects.requireNonNull(getCommand("kit"), "Please check plugin.yml");
kit.setExecutor(this);
kit.setTabCompleter(this);
}
@Override
public boolean onCommand(CommandSender sender, Command command,
String label, String[] args) {
if (!(sender instanceof Player player)) {KitPlugin Part 1 · This paragraph 2/2, sequential connection
sender.sendMessage("Please collect the tool kit in the game");
return true;
}
if (!player.hasPermission("blockacademy.kit")) {
player.sendMessage(Component.text("You have not received the permission yet"));
return true;
}
if (args.length != 1) {
player.sendMessage(Component.text("Usage: /kit miner or /kit builder"));
return true;
}09 / 13
The lower part of the toolkit program
The following page follows immediately. Distribution, remaining items, and replenishment are all placed in the same class. Keep the boundaries between the two @Override methods, and don’t let the creepers count the number of braces for you.
- DistributionaddItem and process the rest
- FeedbackExplain actual results
- CompletionFilter by current prefix
KitPlugin Part 2 · This paragraph 1/2, sequential connection
ItemStack[] items = switch (args[0].toLowerCase(Locale.ROOT)) {
case "miner" -> new ItemStack[] {
new ItemStack(Material.STONE_PICKAXE),
new ItemStack(Material.TORCH, 16)};
case "builder" -> new ItemStack[] {
new ItemStack(Material.OAK_PLANKS, 32),
new ItemStack(Material.GLASS, 16)};
default -> null;
};
if (items == null) {
player.sendMessage(Component.text("Only recognize miner and builder"));
return true;
}
var leftovers = player.getInventory().addItem(items);
for (ItemStack item : leftovers.values()) {
player.getWorld().dropItemNaturally(player.getLocation(), item);
}
player.sendMessage(Component.text(leftovers.isEmpty()
? "The tool kit has been placed in the backpack" : "The backpack is full and the remaining items fall at my feet"));
return true;
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command,
String alias, String[] args) {KitPlugin Part 2 · This paragraph 2/2, sequential connection
if (!sender.hasPermission("blockacademy.kit") || args.length != 1)
return List.of();
String prefix = args[0].toLowerCase(Locale.ROOT);
return List.of("miner", "builder").stream()
.filter(name -> name.startsWith(prefix)).toList();
}
}10 / 13
Walk through the failure path as well
First free up the backpack to do a successful test, and then actively create empty parameters, unfamiliar parameters and a full backpack. The goal of testing is to know what will happen with each input. You can't just declare that you have passed the level just because "I got a pickaxe once."
- NormalBoth packages comply with the formula
- BorderZero parameters, full backpack
- RejectUnknown options, console, no permissions
| Operation | Expected |
|---|---|
| player/kit miner | 1 stone pickaxe and 16 torches |
| player/kit builder | 32 wood panels and 16 glass |
| Console kit miner | Prompt to receive it in the game, no exception |
| /kit or /kit wizard | Give clear feedback and do not send items |
| Collect after the backpack is filled | There are remaining items at your feet, the information is accurate |
| Enter /kit m and press Tab | Complete miner |
11 / 13
Make commands easier to maintain
When there are more and more commands, each branch needs to write a huge distribution code, and repairing it once is like digging an entire mountain. Divide the recipe into a method, and the command method is only responsible for checking and calling.
Stop and think about it: What judgment should be completed before reading args[0]? Why can't zero parameters be remedied by the subsequent recipe branch?
- Clear responsibilitiesCommand responsible for inspection
- Formula methodOnly return item list
- Test synchronizationChanging the rules also changes the expectations
Extract a recipe method. See the description in this section for the location.
private ItemStack[] minerKit() {
return new ItemStack[] {
new ItemStack(Material.STONE_PICKAXE),
new ItemStack(Material.TORCH, 16)};
}The help messages must also be consistent. See the description in this section for the location.
player.sendMessage(Component.text("Usage: /kit miner or /kit builder"));
// plugin.yml Medium usage Write the same selection range- Change the case to MINER and expect the miner package to still be recognized.
- Changed unknown option to wizard, no expected item changes.
- Change the tool kit quantity to the new value in the recipe table, and then update the acceptance record.
12 / 13
Expansion challenges and own acceptance records
Leave the source code, actual running results and a problem record. Explain it in your own words first, and then run the verification; where the results are different from the predictions, they are often the most worthy of discussion.
- Wooden PickaxeImplement name greetings
- Iron PickaxeComplete two kinds of packages and failure records
- Diamond PickaxeIncreased independent cooldown per player
- Wooden Pickaxe: Implement /hello, sending greetings with names to players; the console can also get reasonable prompts.
- Iron Pickaxe: Complete two tool kits, submit empty parameters and full backpack test records.
- Diamond Pickaxe: After learning the 34th expansion, receive the command to add a 30-second cooldown for each player, and verify that the two players do not affect each other.
- Acceptance requirements: Use players and consoles to test separately, and complete scenarios of no permissions, zero parameters, unknown formulas, and full backpacks; items will not be issued if the confirmation fails.
| I can complete it independently | Mastered | Practice again |
|---|---|---|
| First check the sender and parameters | □ | □ |
| Can handle the remaining items in the backpack | □ | □ |
| Able to explain authority and completion | □ | □ |
13 / 13
Leave the evidence for the next adventure
Divide "can compile", "number rules pass" and "actual performance of the game is correct" into three columns. Scenarios that are not running are written to be tested; when bugs are discovered, trigger conditions, expected, actual, minimum repairs, and retest results are recorded.
| Category | The operation you selected | Evidence left behind |
|---|---|---|
| Normal | A successful path for this lesson | Version and actual output |
| Border | The moment before the end, the maximum value or the full backpack | Compare item by item with contract |
| Reject | Wrong parameters, no permissions or irrelevant events | The feedback is clear and the status has not been changed by mistake. |
- Explain why each arrow in this lesson points from here to there; the parallel cards have no sequential meaning.
- First change a rule, then modify the description and expectations at the same time, and retest with the same input.
TAKE IT WITH YOU
Take the lesson offline
The complete lesson, code, diagrams and exercises, in your preferred language.
