added comprehensive interactive help book

This commit is contained in:
2026-02-04 20:12:49 -05:00
parent 4251641bc6
commit e5bc3d1f14
2 changed files with 158 additions and 3 deletions

View File

@@ -11,7 +11,7 @@ import party.cybsec.oyeshops.OyeShopsPlugin;
import party.cybsec.oyeshops.model.PendingActivation;
import party.cybsec.oyeshops.model.Shop;
import party.cybsec.oyeshops.permission.PermissionManager;
import party.cybsec.oyeshops.listener.ShopActivationListener;
import party.cybsec.oyeshops.gui.HelpBook;
import java.sql.SQLException;
import java.util.ArrayList;
@@ -42,12 +42,13 @@ public class AdminCommands implements CommandExecutor, TabCompleter {
case "toggle" -> handleToggle(sender);
case "notify" -> handleNotifyToggle(sender);
case "info" -> handleInfo(sender);
case "help" -> handleHelp(sender);
case "reload" -> handleReload(sender);
case "inspect", "i" -> handleInspect(sender);
case "spoof", "s" -> handleSpoof(sender);
case "unregister", "delete", "remove" -> handleUnregister(sender, args);
case "_activate" -> handleActivate(sender, args);
default -> sendHelp(sender);
default -> handleHelp(sender);
}
return true;
@@ -55,6 +56,8 @@ public class AdminCommands implements CommandExecutor, TabCompleter {
private void sendHelp(CommandSender sender) {
sender.sendMessage(Component.text("=== oyeshops commands ===", NamedTextColor.GOLD));
sender.sendMessage(Component.text("/oyeshops help", NamedTextColor.YELLOW)
.append(Component.text(" - open interactive guide", NamedTextColor.GRAY)));
sender.sendMessage(Component.text("/oyeshops on", NamedTextColor.YELLOW)
.append(Component.text(" - enable shop creation", NamedTextColor.GRAY)));
sender.sendMessage(Component.text("/oyeshops off", NamedTextColor.YELLOW)
@@ -86,6 +89,14 @@ public class AdminCommands implements CommandExecutor, TabCompleter {
sender.sendMessage(Component.text("cybsec made this plugin", NamedTextColor.GRAY));
}
private void handleHelp(CommandSender sender) {
if (sender instanceof Player player) {
HelpBook.open(player);
} else {
sendHelp(sender);
}
}
private void handleReload(CommandSender sender) {
if (!PermissionManager.isAdmin(sender)) {
sender.sendMessage(Component.text("no permission", NamedTextColor.RED));
@@ -342,7 +353,8 @@ public class AdminCommands implements CommandExecutor, TabCompleter {
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
List<String> completions = new ArrayList<>();
if (args.length == 1) {
List<String> subCommands = new ArrayList<>(List.of("on", "off", "toggle", "notify", "enable", "disable"));
List<String> subCommands = new ArrayList<>(
List.of("help", "on", "off", "toggle", "notify", "info", "enable", "disable"));
if (PermissionManager.isAdmin(sender)) {
subCommands.addAll(List.of("reload", "inspect", "spoof", "unregister"));
}

View File

@@ -0,0 +1,143 @@
package party.cybsec.oyeshops.gui;
import net.kyori.adventure.inventory.Book;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
/**
* utility to open an interactive help book for players
* all text is lowercase for consistency
*/
public class HelpBook {
public static void open(Player player) {
List<Component> pages = new ArrayList<>();
// page 1: introduction
pages.add(Component.text()
.append(Component.text("oyeshops guide", NamedTextColor.GOLD, TextDecoration.BOLD))
.append(Component.newline())
.append(Component.newline())
.append(Component.text("welcome to the simple item barter system.", NamedTextColor.DARK_GRAY))
.append(Component.newline())
.append(Component.newline())
.append(Component.text("steps to start:", NamedTextColor.GRAY))
.append(Component.newline())
.append(Component.text("1. type ", NamedTextColor.BLACK))
.append(Component.text("/oyes on", NamedTextColor.BLUE))
.append(Component.newline())
.append(Component.text("2. place a container", NamedTextColor.BLACK))
.append(Component.newline())
.append(Component.text("3. place a wall sign", NamedTextColor.BLACK))
.build());
// page 2: the sign format
pages.add(Component.text()
.append(Component.text("creating a shop", NamedTextColor.GOLD, TextDecoration.BOLD))
.append(Component.newline())
.append(Component.newline())
.append(Component.text("write your trade on the sign like this:", NamedTextColor.DARK_GRAY))
.append(Component.newline())
.append(Component.newline())
.append(Component.text("line 1: ", NamedTextColor.GRAY))
.append(Component.text("1 diamond", NamedTextColor.BLACK))
.append(Component.newline())
.append(Component.text("line 2: ", NamedTextColor.GRAY))
.append(Component.text("for", NamedTextColor.BLACK))
.append(Component.newline())
.append(Component.text("line 3: ", NamedTextColor.GRAY))
.append(Component.text("64 dirt", NamedTextColor.BLACK))
.append(Component.newline())
.append(Component.newline())
.append(Component.text("(order doesn't matter, it shows a confirmation)", NamedTextColor.DARK_GRAY))
.build());
// page 3: auto detection
pages.add(Component.text()
.append(Component.text("auto detection", NamedTextColor.GOLD, TextDecoration.BOLD))
.append(Component.newline())
.append(Component.newline())
.append(Component.text("lazy? just put your items in the chest and write:", NamedTextColor.DARK_GRAY))
.append(Component.newline())
.append(Component.newline())
.append(Component.text("auto", NamedTextColor.BLUE, TextDecoration.BOLD))
.append(Component.newline())
.append(Component.text("for 10 gold", NamedTextColor.BLACK))
.append(Component.newline())
.append(Component.newline())
.append(Component.text("the plugin will see what's in the chest and fill it in for you.",
NamedTextColor.DARK_GRAY))
.build());
// page 4: protection and ownership
pages.add(Component.text()
.append(Component.text("ownership rules", NamedTextColor.GOLD, TextDecoration.BOLD))
.append(Component.newline())
.append(Component.newline())
.append(Component.text("to prevent stealing, you can only make shops on containers you placed ",
NamedTextColor.DARK_GRAY))
.append(Component.text("this session", NamedTextColor.BLACK, TextDecoration.ITALIC))
.append(Component.text(".", NamedTextColor.DARK_GRAY))
.append(Component.newline())
.append(Component.newline())
.append(Component.text(
"if the server restarts, you can't turn old chests into shops. place a fresh one!",
NamedTextColor.DARK_GRAY))
.build());
// page 5: containers
pages.add(Component.text()
.append(Component.text("supported blocks", NamedTextColor.GOLD, TextDecoration.BOLD))
.append(Component.newline())
.append(Component.newline())
.append(Component.text("- chests", NamedTextColor.BLACK))
.append(Component.newline())
.append(Component.text("- barrels", NamedTextColor.BLACK))
.append(Component.newline())
.append(Component.text("- trapped chests", NamedTextColor.BLACK))
.append(Component.newline())
.append(Component.newline())
.append(Component.text("double chests are fully supported. both halves are protected.",
NamedTextColor.DARK_GRAY))
.build());
// page 6: utility commands
pages.add(Component.text()
.append(Component.text("handy commands", NamedTextColor.GOLD, TextDecoration.BOLD))
.append(Component.newline())
.append(Component.newline())
.append(Component.text("/oyes notify", NamedTextColor.BLUE))
.append(Component.newline())
.append(Component.text("get alerts when your shops run out of items.", NamedTextColor.DARK_GRAY))
.append(Component.newline())
.append(Component.newline())
.append(Component.text("/oyes info", NamedTextColor.BLUE))
.append(Component.newline())
.append(Component.text("see who made this plugin.", NamedTextColor.DARK_GRAY))
.build());
// page 7: tips
pages.add(Component.text()
.append(Component.text("pro tips", NamedTextColor.GOLD, TextDecoration.BOLD))
.append(Component.newline())
.append(Component.newline())
.append(Component.text("- use wall signs only.", NamedTextColor.BLACK))
.append(Component.newline())
.append(Component.text("- use abbreviations like ", NamedTextColor.BLACK))
.append(Component.text("dia", NamedTextColor.BLUE))
.append(Component.text(" for diamond.", NamedTextColor.BLACK))
.append(Component.newline())
.append(Component.text("- shops are ", NamedTextColor.BLACK))
.append(Component.text("off", NamedTextColor.RED))
.append(Component.text(" by default to prevent accidents.", NamedTextColor.BLACK))
.build());
Book book = Book.book(Component.text("oyeshops manual"), Component.text("oyeshops"), pages);
player.openBook(book);
}
}