Makes encryption signs support admin decryption prevention
All checks were successful
EpicKnarvik97/Books-Without-Borders/pipeline/head This commit looks good

This commit is contained in:
2026-01-08 12:19:15 +01:00
parent 57855b22f1
commit 51b77acb0c
4 changed files with 63 additions and 45 deletions

View File

@@ -63,35 +63,35 @@ Books without Borders has got your back!
An in-game description of available commands is available through the /bwb command.
| Command | Alias | Arguments | Permission | Description |
|----------------------|---------------|----------------------------------------------------------------------------------|-----------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| /addbooktitlepage | bwbTitlePage | \[page index] \[title~description] | bookswithoutborders.addtitlepage | Adds a blank page, title page or chapter page depending on input and whether the book is signed. The title author separator (default `~`) is used to separate the input into title,paragraph1,paragraph2,... |
| /bookswithoutborders | bwb | None | | Displays information about commands (and permissions if the user has bookswithoutborders.admin) |
| /clearbook | bwbClear | None | bookswithoutborders.clear | Removes all text from the held un-signed book |
| /copybook | bwbCopy | \<# of copies> | bookswithoutborders.copy | Copies the book the player is holding |
| /createbwbsign | bwbSign | \<give/encrypt/decrypt> \[book identifier/password] \[encryption style] | bookswithoutborders.signs | Creates a books without borders sign, as specified. This command is not restricted by the normal sign line text limit, and can load books with any name length for give signs. Encrypt and decrypts signs can be created manually just fine, but using this avoids manual formatting. |
| /decryptbook | bwbDecrypt | \<key> | bookswithoutborders.decrypt | Decrypts the book the player is holding. "key" is required and MUST be IDENTICAL to the key used to encrypt the held book |
| /deletebook | bwbDelete | \<file name or number> | bookswithoutborders.delete | Deletes the specified file in the player's directory |
| /deletebookpage | bwbDeletePage | \<page> | bookswithoutborders.deletepage | Deletes one page from a book |
| /deletepublicbook | bwbDeleteP | \<file name or number> | bookswithoutborders.admin | Same as deletebook, but deletes files in the public directory |
| /editbwbconfig | bwbConfig | \<option> \[value] \[value] ... | bookswithoutborders.admin | Edits a configuration option in the config file. Correct usage heavily depends on the specific value you want to change. |
| /encryptbook | bwbEncrypt | \<key> \[encryption style] | bookswithoutborders.encrypt | Encrypts the book the player is holding. "key" is required and can be any phrase or number excluding spaces. "style" is not required. Possible values are "dna", "substitution", "aes", "onetimepad" and "magic", unless real encryption is enabled, which limits available algorithms. |
| /formatbook | bwbFormat | None | bookswithoutborders.format | Formats the held written book (converts color and formatting codes to the corresponding formatted text) |
| /givebook | bwbGive | \<file name or number> \<playername> \[# of copies (num)] \[signed (true/false)] | bookswithoutborders.give | Gives the selected player a book from your personal directory |
| /givepublicbook | bwbGiveP | \<file name or number> \<playername> \[# of copies (num)] \[signed (true/false)] | bookswithoutborders.givepublic | Same as givebook, but uses books from the public directory |
| /groupencryptbook | bwbGEncrypt | \<group name> \<key> \[encryption style] | bookswithoutborders.groupencrypt | Makes an encrypted book that only players with the "bookswithoutborders.decrypt.<group>" permission can decrypt. It's always auto-decrypted, so the key only matters for scrambling the contents. |
| /loadbook | bwbLoad | \<file name or number> \[# of copies] \[signed (true/false)] | bookswithoutborders.load | Creates a book from the specified file and gives it to the player. If no file is specified, a list of available files is returned. If true is specified, the book will be signed, if false it will be unsigned |
| /loadpublicbook | bwbLoadP | \<file name or number> \[# of copies] \[signed (true/false)] | bookswithoutborders.loadpublic | Same as loadbook, but views files in the public directory |
| /migratebooks | bwbMigrate | None | bookswithoutborders.admin | Migrates all txt books to yml, and fixes any incorrect filenames. |
| /reload | bwbReload | None | bookswithoutborders.reload | Reloads BwB's configuration file |
| /savebook | bwbSave | \[overwrite (true/false)] | bookswithoutborders.save | Saves the book the player is holding to a text file in a private directory. If true is specified, a book of the same name by the same author will be overwritten by the new book |
| /savepublicbook | bwbSaveP | \[overwrite (true/false)] | bookswithoutborders.savepublic | Same as savebook, but saves files in the public directory |
| /setbookauthor | bwbAuthor | \<author> | bookswithoutborders.setauthor | Sets the author of the book the player is holding |
| /setbookgeneration | bwbGeneration | \<generation> | bookswithoutborders.setgeneration | Sets the generation of the held book (ORIGINAL, COPY_OF_ORIGINAL, COPY_OF_COPY, TATTERED) |
| /setbookshelfdata | bwbShelfData | \<delete/name/lore> \text> \[more text] | bookswithoutborders.editbookshelf | Sets the name/lore for a bookshelf which is shown when peeking at its contents. |
| /setlore | bwbLore | \<new lore> | bookswithoutborders.setlore | Sets the lore of the item the player is holding. Insert the `separator.loreLine` character to force a new line ("~" by default) |
| /settitle | bwbTitle | \<title> \[title] ... \[setDisplayName (true/false)] | bookswithoutborders.settitle | Sets the title of the book or the display name of the item the player is holding. Add a true at the end (`/settitle some title true`) to set a book's display name instead of its title. |
| /unsignbook | bwbUnsign | None | bookswithoutborders.unsign | Un-signs the book the player is holding |
| Command | Alias | Arguments | Permission | Description |
|----------------------|---------------|-----------------------------------------------------------------------------------------------------|-----------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| /addbooktitlepage | bwbTitlePage | \[page index] \[title~description] | bookswithoutborders.addtitlepage | Adds a blank page, title page or chapter page depending on input and whether the book is signed. The title author separator (default `~`) is used to separate the input into title,paragraph1,paragraph2,... |
| /bookswithoutborders | bwb | None | | Displays information about commands (and permissions if the user has bookswithoutborders.admin) |
| /clearbook | bwbClear | None | bookswithoutborders.clear | Removes all text from the held un-signed book |
| /copybook | bwbCopy | \<# of copies> | bookswithoutborders.copy | Copies the book the player is holding |
| /createbwbsign | bwbSign | \<give/encrypt/decrypt> \[book identifier/password] \[encryption style] \[disable admin decryption] | bookswithoutborders.signs | Creates a books without borders sign, as specified. This command is not restricted by the normal sign line text limit, and can load books with any name length for give signs. Encrypt and decrypts signs can be created manually just fine, but using this avoids manual formatting. |
| /decryptbook | bwbDecrypt | \<key> | bookswithoutborders.decrypt | Decrypts the book the player is holding. "key" is required and MUST be IDENTICAL to the key used to encrypt the held book |
| /deletebook | bwbDelete | \<file name or number> | bookswithoutborders.delete | Deletes the specified file in the player's directory |
| /deletebookpage | bwbDeletePage | \<page> | bookswithoutborders.deletepage | Deletes one page from a book |
| /deletepublicbook | bwbDeleteP | \<file name or number> | bookswithoutborders.admin | Same as deletebook, but deletes files in the public directory |
| /editbwbconfig | bwbConfig | \<option> \[value] \[value] ... | bookswithoutborders.admin | Edits a configuration option in the config file. Correct usage heavily depends on the specific value you want to change. |
| /encryptbook | bwbEncrypt | \<key> \[encryption style] | bookswithoutborders.encrypt | Encrypts the book the player is holding. "key" is required and can be any phrase or number excluding spaces. "style" is not required. Possible values are "dna", "substitution", "aes", "onetimepad" and "magic", unless real encryption is enabled, which limits available algorithms. |
| /formatbook | bwbFormat | None | bookswithoutborders.format | Formats the held written book (converts color and formatting codes to the corresponding formatted text) |
| /givebook | bwbGive | \<file name or number> \<playername> \[# of copies (num)] \[signed (true/false)] | bookswithoutborders.give | Gives the selected player a book from your personal directory |
| /givepublicbook | bwbGiveP | \<file name or number> \<playername> \[# of copies (num)] \[signed (true/false)] | bookswithoutborders.givepublic | Same as givebook, but uses books from the public directory |
| /groupencryptbook | bwbGEncrypt | \<group name> \<key> \[encryption style] | bookswithoutborders.groupencrypt | Makes an encrypted book that only players with the "bookswithoutborders.decrypt.<group>" permission can decrypt. It's always auto-decrypted, so the key only matters for scrambling the contents. |
| /loadbook | bwbLoad | \<file name or number> \[# of copies] \[signed (true/false)] | bookswithoutborders.load | Creates a book from the specified file and gives it to the player. If no file is specified, a list of available files is returned. If true is specified, the book will be signed, if false it will be unsigned |
| /loadpublicbook | bwbLoadP | \<file name or number> \[# of copies] \[signed (true/false)] | bookswithoutborders.loadpublic | Same as loadbook, but views files in the public directory |
| /migratebooks | bwbMigrate | None | bookswithoutborders.admin | Migrates all txt books to yml, and fixes any incorrect filenames. |
| /reload | bwbReload | None | bookswithoutborders.reload | Reloads BwB's configuration file |
| /savebook | bwbSave | \[overwrite (true/false)] | bookswithoutborders.save | Saves the book the player is holding to a text file in a private directory. If true is specified, a book of the same name by the same author will be overwritten by the new book |
| /savepublicbook | bwbSaveP | \[overwrite (true/false)] | bookswithoutborders.savepublic | Same as savebook, but saves files in the public directory |
| /setbookauthor | bwbAuthor | \<author> | bookswithoutborders.setauthor | Sets the author of the book the player is holding |
| /setbookgeneration | bwbGeneration | \<generation> | bookswithoutborders.setgeneration | Sets the generation of the held book (ORIGINAL, COPY_OF_ORIGINAL, COPY_OF_COPY, TATTERED) |
| /setbookshelfdata | bwbShelfData | \<delete/name/lore> \text> \[more text] | bookswithoutborders.editbookshelf | Sets the name/lore for a bookshelf which is shown when peeking at its contents. |
| /setlore | bwbLore | \<new lore> | bookswithoutborders.setlore | Sets the lore of the item the player is holding. Insert the `separator.loreLine` character to force a new line ("~" by default) |
| /settitle | bwbTitle | \<title> \[title] ... \[setDisplayName (true/false)] | bookswithoutborders.settitle | Sets the title of the book or the display name of the item the player is holding. Add a true at the end (`/settitle some title true`) to set a book's display name instead of its title. |
| /unsignbook | bwbUnsign | None | bookswithoutborders.unsign | Un-signs the book the player is holding |
### Permissions:
@@ -156,7 +156,9 @@ author). Use the `createbwbsign` command in order to specify book names of any l
#### Encrypt sign
The **_encrypt_**-sign must have **\[Encrypt]** on its second line. The third line must contain the encryption key The
fourth line can be empty or contain "dna" for dna-based encryption.
fourth line can be empty or contain the encryption type (aes,dna,substitution,magic,onetimepad). If real encryption and
prevent admin decryption is enabled, "AES true" can be used as the encryption type to prevent admin decryption for any
book encrypted by the sign.
#### Decrypt sign

View File

@@ -8,6 +8,7 @@ import net.knarcraft.bookswithoutborders.gui.PagedBookIndex;
import net.knarcraft.bookswithoutborders.state.BookDirectory;
import net.knarcraft.bookswithoutborders.utility.BookFileUtil;
import net.knarcraft.bookswithoutborders.utility.InputCleaningUtil;
import net.knarcraft.bookswithoutborders.utility.TabCompletionTypeUtil;
import net.knarcraft.knarlib.formatting.FormatBuilder;
import net.knarcraft.knarlib.util.SignHelper;
import net.knarcraft.knarlib.util.TabCompletionHelper;
@@ -107,6 +108,9 @@ public class CommandCreateBwBSign implements TabExecutor {
}
}
return TabCompletionHelper.filterMatchingStartsWith(encryptionStyles, arguments[2]);
} else if (arguments.length == 4 && EncryptionStyle.getFromString(arguments[2]) != null &&
BooksWithoutBorders.getConfiguration().allowPreventAdminDecryption()) {
return TabCompletionHelper.filterMatchingStartsWith(TabCompletionTypeUtil.getBooleans(), arguments[3]);
}
return List.of();
}
@@ -119,14 +123,21 @@ public class CommandCreateBwBSign implements TabExecutor {
* @return <p>True if the command was used correctly</p>
*/
private boolean createEncryptSign(@NotNull String[] arguments, @NotNull SignSide side) {
if (arguments.length < 2 || arguments.length > 3) {
if (arguments.length < 2 || arguments.length > 4) {
return false;
}
String password = arguments[1];
EncryptionStyle encryptionStyle = null;
if (arguments.length == 3) {
boolean bypassAdminDecryption = false;
if (arguments.length == 3 || arguments.length == 4) {
encryptionStyle = EncryptionStyle.getFromString(arguments[2]);
// Retain admin decryption prevention on the sign
if (arguments.length == 4 && encryptionStyle == EncryptionStyle.AES &&
BooksWithoutBorders.getConfiguration().allowPreventAdminDecryption()) {
bypassAdminDecryption = Boolean.parseBoolean(arguments[3]);
}
}
// Alter sign text
@@ -135,7 +146,7 @@ public class CommandCreateBwBSign implements TabExecutor {
if (encryptionStyle == null) {
side.setLine(3, "");
} else {
side.setLine(3, ChatColor.DARK_BLUE + encryptionStyle.toString());
side.setLine(3, ChatColor.DARK_BLUE + encryptionStyle.toString() + " " + bypassAdminDecryption);
}
return true;
}

View File

@@ -1,5 +1,6 @@
package net.knarcraft.bookswithoutborders.listener;
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
import net.knarcraft.bookswithoutborders.config.Permission;
import net.knarcraft.bookswithoutborders.config.translation.GiveMessage;
import net.knarcraft.bookswithoutborders.config.translation.Placeholder;
@@ -183,8 +184,22 @@ public class SignEventListener implements Listener {
}
player.closeInventory();
EncryptionStyle encryptionStyle;
boolean preventAdminDecryption = false;
String line = getCleanLine(lines[3]);
if (line.contains(" ")) {
String[] parts = line.split(" ");
encryptionStyle = Objects.requireNonNullElse(EncryptionStyle.getFromString(parts[0]), EncryptionStyle.AES);
preventAdminDecryption = Boolean.parseBoolean(parts[1]) &&
BooksWithoutBorders.getConfiguration().allowPreventAdminDecryption() &&
player.hasPermission(Permission.PREVENT_ADMIN_DECRYPTION.toString());
} else {
encryptionStyle = Objects.requireNonNullElse(EncryptionStyle.getFromString(getCleanLine(lines[3])), EncryptionStyle.AES);
}
ItemStack encryptedBook = EncryptedBookUtil.encryptBook(player, ItemSlot.fromEquipmentSlot(hand), getPassword(lines),
getEncryptionStyle(lines), false);
encryptionStyle, preventAdminDecryption);
if (encryptedBook != null) {
EncryptionUtil.markEncrypted(encryptedBook);
player.getInventory().setItem(hand, encryptedBook);
@@ -334,17 +349,6 @@ public class SignEventListener implements Listener {
return isValid;
}
/**
* Gets the encryption style specified on the given sign
*
* @param lines <p>The lines to parse</p>
* @return <p>The encryption style</p>
*/
@NotNull
private EncryptionStyle getEncryptionStyle(@NotNull String[] lines) {
return Objects.requireNonNullElse(EncryptionStyle.getFromString(getCleanLine(lines[3])), EncryptionStyle.AES);
}
/**
* Gets the password specified on the given sign
*

View File

@@ -237,6 +237,7 @@ commands:
If creating an encrypt or a decrypt sign, the second argument will be treated as the encryption/decryption password
If creating an encrypt sign, the optional third argument is the encryption style to use. Possible values are
"dna", "substitution", "aes", "oneTimePad" and "magic"
If enabled, the fourth arguments accept a positive boolean value (true/1) to disable admin decryption for encrypted books.
aliases:
- bwbSign
usage: /<command> <give/encrypt/decrypt> [book identifier/password] [encryption style]