Makes the addTitlePage command's output translatable
All checks were successful
EpicKnarvik97/Books-Without-Borders/pipeline/head This commit looks good

This commit is contained in:
2025-08-15 16:24:27 +02:00
parent 63ca95d247
commit 67a16bc604
7 changed files with 121 additions and 53 deletions

View File

@@ -3,9 +3,9 @@ package net.knarcraft.bookswithoutborders.command;
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
import net.knarcraft.bookswithoutborders.config.Translatable;
import net.knarcraft.bookswithoutborders.utility.BookFormatter;
import net.knarcraft.bookswithoutborders.utility.BookHelper;
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
import net.knarcraft.knarlib.formatting.StringFormatter;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@@ -42,8 +42,11 @@ public class CommandAddTitlePage implements TabExecutor {
int index;
if (arguments.length < 1) {
if (InventoryHelper.notHoldingOneWrittenBookCheck(player, "You must be holding a written book to " +
"add an author title page!", "You cannot add an author title page to two books at once!")) {
if (InventoryHelper.notHoldingOneWrittenBookCheck(player,
stringFormatter.replacePlaceholder(Translatable.ERROR_NOT_HOLDING_WRITTEN_BOOK, "{action}",
stringFormatter.getUnFormattedColoredMessage(Translatable.ACTION_ADD_TITLE_AUTHOR_PAGE)),
stringFormatter.replacePlaceholder(Translatable.ERROR_ONLY_ONE_BOOK, "{action}",
stringFormatter.getUnFormattedColoredMessage(Translatable.ACTION_ADD_TITLE_AUTHOR_PAGE)))) {
return false;
}
@@ -52,7 +55,7 @@ public class CommandAddTitlePage implements TabExecutor {
try {
index = Integer.parseInt(arguments[0]) - 1;
} catch (NumberFormatException exception) {
BooksWithoutBorders.sendErrorMessage(sender, "Invalid page index given!");
stringFormatter.displayErrorMessage(sender, Translatable.ERROR_INVALID_BOOK_PAGE);
return false;
}
}
@@ -70,30 +73,37 @@ public class CommandAddTitlePage implements TabExecutor {
BookMeta bookMeta = (BookMeta) heldBook.getItemMeta();
if (bookMeta == null) {
BooksWithoutBorders.sendErrorMessage(sender, "Unable to get metadata for the held book!");
stringFormatter.displayErrorMessage(sender, Translatable.ERROR_METADATA_MISSING);
return false;
}
List<String> pages = new ArrayList<>(bookMeta.getPages());
if (index < 0) {
BooksWithoutBorders.sendErrorMessage(sender, "The given page index is out of bounds!");
stringFormatter.displayErrorMessage(sender, Translatable.ERROR_INVALID_BOOK_PAGE);
return false;
}
if (title == null && heldBook.getType() == Material.WRITTEN_BOOK) {
// Add a page with the book title and book author
String loreSeparator = BooksWithoutBorders.getConfiguration().getLoreSeparator();
String pageText = formatTitle(stringFormatter.replacePlaceholders(Translatable.NEUTRAL_TITLE_PAGE_TITLE_AUTHOR_FORMAT,
List.of("{title}", "{separator}", "{author}"), List.of(BookHelper.getBookTitle(bookMeta),
loreSeparator, BookHelper.getBookAuthor(bookMeta, null))));
if (index > pages.size()) {
pages.add(formatTitle(bookMeta.getTitle() + loreSeparator + "By: " + bookMeta.getAuthor()));
pages.add(pageText);
} else {
pages.add(index, formatTitle(bookMeta.getTitle() + loreSeparator + "By: " + bookMeta.getAuthor()));
pages.add(index, pageText);
}
} else if (title == null) {
// Add a blank page
if (index > pages.size()) {
pages.add("");
} else {
pages.add(index, "");
}
} else {
// Add a custom chapter page
if (index > pages.size()) {
pages.add(formatTitle(title));
} else {
@@ -102,7 +112,7 @@ public class CommandAddTitlePage implements TabExecutor {
}
bookMeta.setPages(pages);
heldBook.setItemMeta(bookMeta);
BooksWithoutBorders.sendSuccessMessage(sender, "Title page added!");
stringFormatter.displaySuccessMessage(sender, Translatable.SUCCESS_TITLE_PAGE_ADDED);
return true;
}
@@ -113,18 +123,21 @@ public class CommandAddTitlePage implements TabExecutor {
* @return <p>The formatted input</p>
*/
private String formatTitle(@NotNull String input) {
StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter();
String loreSeparator = BooksWithoutBorders.getConfiguration().getLoreSeparator();
if (input.contains(loreSeparator)) {
String[] parts = input.split(loreSeparator);
StringBuilder output = new StringBuilder("\n");
output.append(ChatColor.UNDERLINE).append(ChatColor.BOLD).append(BookFormatter.stripColor(parts[0])).append(ChatColor.RESET);
StringBuilder output = new StringBuilder();
output.append(stringFormatter.replacePlaceholder(Translatable.NEUTRAL_TITLE_PAGE_HEADER_FORMAT,
"{header}", BookFormatter.stripColor(parts[0])));
for (int i = 1; i < parts.length; i++) {
output.append("\n").append("\n").append(ChatColor.ITALIC).append(BookFormatter.stripColor(parts[i])).append(ChatColor.RESET);
output.append(stringFormatter.replacePlaceholder(Translatable.NEUTRAL_TITLE_PAGE_TEXT_FORMAT,
"{text}", BookFormatter.stripColor(parts[i])));
}
return output.toString();
} else {
return ChatColor.UNDERLINE + ChatColor.BOLD.toString() + input;
return input;
}
}

View File

@@ -35,7 +35,7 @@ public class CommandFormat implements TabExecutor {
stringFormatter.displayErrorMessage(sender, Translatable.ERROR_NOT_HOLDING_ANY_BOOK);
return false;
}
BookMeta meta = (BookMeta) heldBook.getItemMeta();
if (meta == null) {

View File

@@ -48,6 +48,11 @@ public enum Translatable implements TranslatableMessage {
*/
SUCCESS_GIVE_RECEIVED,
/**
* The success message displayed when a title page is successfully added
*/
SUCCESS_TITLE_PAGE_ADDED,
/**
* The error to display when the console attempts to run a player-only command
*/
@@ -188,6 +193,11 @@ public enum Translatable implements TranslatableMessage {
*/
ERROR_NOT_HOLDING_ANY_BOOK,
/**
* The error displayed when a book page is specified outside the allowed range.
*/
ERROR_INVALID_BOOK_PAGE,
/**
* The header displayed before printing all commands
*/
@@ -223,6 +233,26 @@ public enum Translatable implements TranslatableMessage {
*/
NEUTRAL_UNKNOWN_AUTHOR,
/**
* The translation of unknown title for a book
*/
NEUTRAL_UNKNOWN_TITLE,
/**
* The format used when generating a title + author title page
*/
NEUTRAL_TITLE_PAGE_TITLE_AUTHOR_FORMAT,
/**
* The formatting used when formatting the header on a title page
*/
NEUTRAL_TITLE_PAGE_HEADER_FORMAT,
/**
* The format used when formatting text on a title page
*/
NEUTRAL_TITLE_PAGE_TEXT_FORMAT,
/**
* The translation of the copy action
*/
@@ -247,6 +277,11 @@ public enum Translatable implements TranslatableMessage {
* The translation of the format action
*/
ACTION_FORMAT,
/**
* The translation of the add title page action
*/
ACTION_ADD_TITLE_AUTHOR_PAGE,
;
@Override

View File

@@ -1,9 +1,9 @@
package net.knarcraft.bookswithoutborders.listener;
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
import net.knarcraft.bookswithoutborders.config.Translatable;
import net.knarcraft.bookswithoutborders.container.Bookshelf;
import net.knarcraft.bookswithoutborders.handler.BookshelfHandler;
import net.knarcraft.bookswithoutborders.utility.BookHelper;
import net.knarcraft.bookswithoutborders.utility.IntegerToRomanConverter;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Location;
@@ -147,18 +147,8 @@ public class BookshelfListener implements Listener {
*/
@NotNull
private String getBookDescription(@NotNull BookMeta bookMeta) {
String title;
String author;
if (!bookMeta.hasTitle() || bookMeta.getTitle() == null) {
title = "Untitled";
} else {
title = bookMeta.getTitle();
}
if (!bookMeta.hasAuthor() || bookMeta.getAuthor() == null) {
author = BooksWithoutBorders.getStringFormatter().getUnFormattedColoredMessage(Translatable.NEUTRAL_UNKNOWN_AUTHOR);
} else {
author = bookMeta.getAuthor();
}
String title = BookHelper.getBookTitle(bookMeta);
String author = BookHelper.getBookAuthor(bookMeta, null);
return ChatColor.of("#686868") + "[Q]" + ChatColor.RESET + title + ChatColor.RESET + " by " + author;
}

View File

@@ -162,29 +162,8 @@ public final class BookHelper {
@NotNull
public static String getBookFile(@NotNull BookMeta book, @NotNull OfflinePlayer player, boolean isPublic) throws IllegalArgumentException {
String separator = BooksWithoutBorders.getConfiguration().getTitleAuthorSeparator();
String bookName;
if (book.hasTitle()) {
bookName = book.getTitle();
if (bookName == null) {
bookName = "Untitled";
}
} else {
bookName = "Untitled";
}
String playerName = player.getName() == null ? player.getUniqueId().toString() : player.getName();
String authorName;
if ((!book.hasAuthor() || isAuthor(playerName, book.getAuthor())) && !isPublic) {
//Store as unique id to account for name changes
authorName = player.getUniqueId().toString();
} else if (!book.hasAuthor()) {
authorName = player.getName();
} else {
authorName = book.getAuthor();
if (authorName == null) {
authorName = BooksWithoutBorders.getStringFormatter().getUnFormattedColoredMessage(Translatable.NEUTRAL_UNKNOWN_AUTHOR);
}
}
String bookName = getBookTitle(book);
String authorName = getBookAuthor(book, isPublic ? null : player);
if (InputCleaningHelper.cleanString(bookName).contains(separator) ||
InputCleaningHelper.cleanString(authorName).contains(separator)) {
@@ -196,6 +175,47 @@ public final class BookHelper {
return InputCleaningHelper.cleanString(bookName + separator + authorName);
}
/**
* Gets the author of a book, with fallback for unknown author
*
* @param book <p>The book to get the author of</p>
* @param player <p>A player that might be the author (only used for private book folders), or null if dealing with public books</p>
* @return <p>The book author, or an appropriate fallback</p>
*/
public static String getBookAuthor(@NotNull BookMeta book, @Nullable OfflinePlayer player) {
String playerName = player == null ? "?" : (player.getName() == null ? player.getUniqueId().toString() : player.getName());
String authorName;
if ((!book.hasAuthor() || isAuthor(playerName, book.getAuthor())) && player != null) {
//Store as unique id to account for name changes
authorName = player.getUniqueId().toString();
} else if (!book.hasAuthor() && player != null) {
authorName = player.getName();
} else {
authorName = book.getAuthor();
if (authorName == null) {
authorName = BooksWithoutBorders.getStringFormatter().getUnFormattedColoredMessage(Translatable.NEUTRAL_UNKNOWN_AUTHOR);
}
}
return authorName;
}
/**
* Gets a book's name, defaulting to "Untitled" if not named
*
* @param book <p>The book to get the name of</p>
* @return <p>The book's name or "Untitled"</p>
*/
public static String getBookTitle(@NotNull BookMeta book) {
String bookName = null;
if (book.hasTitle()) {
bookName = book.getTitle();
}
if (bookName == null) {
bookName = BooksWithoutBorders.getStringFormatter().getUnFormattedColoredMessage(Translatable.NEUTRAL_UNKNOWN_TITLE);
}
return bookName;
}
/**
* Checks whether the given player is the author of a given book
*

View File

@@ -4,6 +4,7 @@ import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
import net.knarcraft.bookswithoutborders.config.Translatable;
import net.knarcraft.bookswithoutborders.encryption.AESConfiguration;
import net.knarcraft.bookswithoutborders.encryption.EncryptionStyle;
import net.knarcraft.knarlib.formatting.StringFormatter;
import net.knarcraft.knarlib.util.FileHelper;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
@@ -200,13 +201,15 @@ public final class BookToFromTextHelper {
*/
@Nullable
private static BookMeta bookFromYml(@NotNull File file, @NotNull BookMeta bookMetadata) {
StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter();
try {
FileConfiguration bookYml = YamlConfiguration.loadConfiguration(file);
bookMetadata.setGeneration(BookMeta.Generation.valueOf(bookYml.getString("Generation", "ORIGINAL")));
bookMetadata.setTitle(bookYml.getString("Title", "Untitled"));
bookMetadata.setTitle(bookYml.getString("Title",
stringFormatter.getUnFormattedColoredMessage(Translatable.NEUTRAL_UNKNOWN_TITLE)));
bookMetadata.setAuthor(authorFromUUID(bookYml.getString("Author",
BooksWithoutBorders.getStringFormatter().getUnFormattedColoredMessage(Translatable.NEUTRAL_UNKNOWN_AUTHOR))));
stringFormatter.getUnFormattedColoredMessage(Translatable.NEUTRAL_UNKNOWN_AUTHOR))));
bookMetadata.setPages(bookYml.getStringList("Pages"));
bookMetadata.setLore(bookYml.getStringList("Lore"));
} catch (IllegalArgumentException e) {

View File

@@ -8,6 +8,7 @@ en:
SUCCESS_FORMATTED: "Book formatted!"
SUCCESS_GIVE_SENT: "Book sent!"
SUCCESS_GIVE_RECEIVED: "Book received!"
SUCCESS_TITLE_PAGE_ADDED: "Title page added!"
ERROR_PLAYER_ONLY: "This command can only be used by a player!"
ERROR_NOT_HOLDING_WRITTEN_BOOK: "You must be holding a written book to {action} it!"
ERROR_NOT_HOLDING_WRITABLE_BOOK: "You must be holding a writable book to {action} it!"
@@ -18,6 +19,7 @@ en:
ACTION_DECRYPT: "decrypt"
ACTION_ENCRYPT: "encrypt"
ACTION_FORMAT: "format"
ACTION_ADD_TITLE_AUTHOR_PAGE: "add an author title page to"
ERROR_COPY_COUNT_NOT_SPECIFIED: "You must specify the number of copies to be made!"
ERROR_COPY_NEGATIVE_AMOUNT: "Number of copies must be larger than 0!"
ERROR_COPY_INVALID_AMOUNT: |
@@ -43,6 +45,7 @@ en:
ERROR_GIVE_RECIPIENT_FULL: "Receiving player must have space in their inventory to receive books!"
ERROR_GIVE_INVALID_COPIES_AMOUNT: "Invalid number of book copies specified!"
ERROR_GIVE_LOAD_FAILED: "Book failed to load!"
ERROR_INVALID_BOOK_PAGE: "Invalid page index given!"
NEUTRAL_COMMANDS_HEADER: |
&e[] denote optional parameters
<> denote required parameters
@@ -55,4 +58,8 @@ en:
NEUTRAL_COMMANDS_COMMAND: "\n \n&e{usage}: &a{description}"
NEUTRAL_COMMANDS_COMMAND_NO_PERMISSION_REQUIRED: "None"
NEUTRAL_COMMANDS_COMMAND_PERMISSION: " &7{{permission}}"
NEUTRAL_UNKNOWN_AUTHOR: "Unknown"
NEUTRAL_UNKNOWN_AUTHOR: "Unknown"
NEUTRAL_UNKNOWN_TITLE: "Untitled"
NEUTRAL_TITLE_PAGE_TITLE_AUTHOR_FORMAT: "{title}{separator}By: {author}"
NEUTRAL_TITLE_PAGE_HEADER_FORMAT: "\n&n&l{header}&r"
NEUTRAL_TITLE_PAGE_TEXT_FORMAT: "\n\n&o{text}&r"