Compare commits
24 Commits
Author | SHA1 | Date | |
---|---|---|---|
0fe9ccb590 | |||
1a7236cebd | |||
e482e494f8 | |||
0f76c8f869 | |||
6b4e87d33a | |||
40b0fa0baf | |||
31bb26b755 | |||
0e134fcdab | |||
f5ba4db5ac | |||
29d5247c9b | |||
c389c6fbcb | |||
1158820f97 | |||
f9908db88f | |||
738dbe6e30 | |||
3838750f64 | |||
16954f22e3 | |||
6359af02e6 | |||
6ae15acc72 | |||
2c80e4117e | |||
6d539a14df | |||
51371736e4 | |||
2383dfd2ef | |||
04d4bc8303 | |||
184f78d935 |
33
Jenkinsfile
vendored
Normal file
33
Jenkinsfile
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
pipeline {
|
||||||
|
agent any
|
||||||
|
tools {
|
||||||
|
jdk 'JDK17'
|
||||||
|
}
|
||||||
|
stages {
|
||||||
|
stage('Build') {
|
||||||
|
steps {
|
||||||
|
echo 'Building...'
|
||||||
|
sh 'mvn clean & mvn validate & mvn compile'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Test') {
|
||||||
|
steps {
|
||||||
|
echo 'Testing...'
|
||||||
|
sh 'mvn test'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Verify') {
|
||||||
|
steps {
|
||||||
|
echo 'Verifying...'
|
||||||
|
sh 'mvn verify -Dmaven.test.skip=true'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Deploy') {
|
||||||
|
steps {
|
||||||
|
echo 'Deploying...'
|
||||||
|
sh 'mvn deploy -Dmaven.install.skip=true -Dmaven.test.skip=true'
|
||||||
|
archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
17
README.md
17
README.md
@ -30,6 +30,7 @@ Books without Borders has got your back!
|
|||||||
value
|
value
|
||||||
- Change generation of books. Create tattered books for your RPG server!
|
- Change generation of books. Create tattered books for your RPG server!
|
||||||
- Optionally, make it impossible to duplicate the original version of a book
|
- Optionally, make it impossible to duplicate the original version of a book
|
||||||
|
- Optionally, hit a bookshelf while sneaking to display the contained books
|
||||||
|
|
||||||
#### Group encryption
|
#### Group encryption
|
||||||
|
|
||||||
@ -41,13 +42,13 @@ Books without Borders has got your back!
|
|||||||
An in-game description of available commands is available through the /bwb command.
|
An in-game description of available commands is available through the /bwb command.
|
||||||
|
|
||||||
| Command | Arguments | Description |
|
| Command | Arguments | Description |
|
||||||
| --- | --- | --- |
|
|----------------------|----------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| /bookswithoutborders | None | Displays information about commands (and permissions if the user has bookswithoutborders.admin) |
|
| /bookswithoutborders | None | Displays information about commands (and permissions if the user has bookswithoutborders.admin) |
|
||||||
| /copybook | \<# of copies> | Copies the book the player is holding |
|
| /copybook | \<# of copies> | Copies the book the player is holding |
|
||||||
| /decryptbook | \<key> | Decrypts the book the player is holding. "key" is required and MUST be IDENTICAL to the key used to encrypt the held book |
|
| /decryptbook | \<key> | Decrypts the book the player is holding. "key" is required and MUST be IDENTICAL to the key used to encrypt the held book |
|
||||||
| /deletebook | \<file name or number> | Deletes the specified file in the player's directory |
|
| /deletebook | \<file name or number> | Deletes the specified file in the player's directory |
|
||||||
| /deletepublicbook | \<file name or number> | Same as deletebook, but deletes files in the public directory |
|
| /deletepublicbook | \<file name or number> | Same as deletebook, but deletes files in the public directory |
|
||||||
| encryptbook | \<key> \[encryption style] | 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" or "" |
|
| /encryptbook | \<key> \[encryption style] | 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" or "" |
|
||||||
| /formatbook | None | Formats the held written book (converts color and formatting codes to the corresponding formatted text) |
|
| /formatbook | None | Formats the held written book (converts color and formatting codes to the corresponding formatted text) |
|
||||||
| /givebook | \<file name or number> \<playername> \[# of copies (num)] \[signed (true/false)] | Gives the selected player a book from your personal directory |
|
| /givebook | \<file name or number> \<playername> \[# of copies (num)] \[signed (true/false)] | Gives the selected player a book from your personal directory |
|
||||||
| /givepublicbook | \<file name or number> \<playername> \[# of copies (num)] \[signed (true/false)] | Same as givebook, but uses books from the public directory |
|
| /givepublicbook | \<file name or number> \<playername> \[# of copies (num)] \[signed (true/false)] | Same as givebook, but uses books from the public directory |
|
||||||
@ -67,10 +68,10 @@ An in-game description of available commands is available through the /bwb comma
|
|||||||
### Permissions:
|
### Permissions:
|
||||||
|
|
||||||
| Node | Description |
|
| Node | Description |
|
||||||
| --- | --- |
|
|--------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| bookswithoutborders.* | Grants all permissions |
|
| bookswithoutborders.* | Grants all permissions |
|
||||||
| bookswithoutborders.admin | Grants all permissions |
|
| bookswithoutborders.admin | Grants all permissions |
|
||||||
| bookswithoutborders.use | Allows player to use commands to save/load/delete in their personal directory |
|
| bookswithoutborders.use | bookswithoutborders.use - Allows player to use commands to save/load/delete in their personal directory, and peeking at bookshelves if enabled |
|
||||||
| bookswithoutborders.alterbooks | Allows player to change books' data such as lore/title/author/generation/formatting and un-signing books |
|
| bookswithoutborders.alterbooks | Allows player to change books' data such as lore/title/author/generation/formatting and un-signing books |
|
||||||
| bookswithoutborders.reload | Allows player to reload this plugin |
|
| bookswithoutborders.reload | Allows player to reload this plugin |
|
||||||
| bookswithoutborders.format | Allows a player to format a book |
|
| bookswithoutborders.format | Allows a player to format a book |
|
||||||
@ -98,6 +99,7 @@ An in-game description of available commands is available through the /bwb comma
|
|||||||
| bookswithoutborders.setbookprice | Allows player to set the cost of creating a book |
|
| bookswithoutborders.setbookprice | Allows player to set the cost of creating a book |
|
||||||
| bookswithoutborders.setgeneration | Allows player to change the generation of a book (Original, Copy, Copy of Copy) |
|
| bookswithoutborders.setgeneration | Allows player to change the generation of a book (Original, Copy, Copy of Copy) |
|
||||||
| bookswithoutborders.clear | Allows player to clear the contents of the held writable book |
|
| bookswithoutborders.clear | Allows player to clear the contents of the held writable book |
|
||||||
|
| bookswithoutborders.peekbookshelf | Allows player to left-click a bookshelf to see the contents of the shelf |
|
||||||
|
|
||||||
### Signs
|
### Signs
|
||||||
|
|
||||||
@ -106,13 +108,13 @@ line.
|
|||||||
|
|
||||||
#### Give sign
|
#### Give sign
|
||||||
|
|
||||||
The **_give_** sign must have **\[Give]** on its second line. The third and fourth line contains the book to be loaded.
|
The **_give_**-sign must have **\[Give]** on its second line. The third and fourth line contains the book to be loaded.
|
||||||
This can either be a numerical id pointing to a publicly saved book, or the full text identifier of the book (book name,
|
This can either be a numerical id pointing to a publicly saved book, or the full text identifier of the book (book name,
|
||||||
author).
|
author).
|
||||||
|
|
||||||
#### Encrypt sign
|
#### Encrypt sign
|
||||||
|
|
||||||
The **_encrypt_** sign must have **\[Encrypt]** on its second line. The third line must contain the encryption key The
|
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 "dna" for dna-based encryption.
|
||||||
|
|
||||||
#### Decrypt sign
|
#### Decrypt sign
|
||||||
@ -122,7 +124,7 @@ The **_decrypt_** sign must have **\[Decrypt]** on its second line. The third li
|
|||||||
### Configuration options:
|
### Configuration options:
|
||||||
|
|
||||||
| Option | Description |
|
| Option | Description |
|
||||||
| --- | --- |
|
|----------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| Save_Books_in_Yaml_Format | Whether to use YAML for saved books instead of just storing them as text |
|
| Save_Books_in_Yaml_Format | Whether to use YAML for saved books instead of just storing them as text |
|
||||||
| Max_Number_of_Duplicates | The maximum number of duplicates of a saved book allowed |
|
| Max_Number_of_Duplicates | The maximum number of duplicates of a saved book allowed |
|
||||||
| Author_Separator | The separator used to separate the book title and the book author |
|
| Author_Separator | The separator used to separate the book title and the book author |
|
||||||
@ -137,3 +139,4 @@ The **_decrypt_** sign must have **\[Decrypt]** on its second line. The third li
|
|||||||
| Author_Only_Save | Whether to only allow saving a player's own books with /savebook |
|
| Author_Only_Save | Whether to only allow saving a player's own books with /savebook |
|
||||||
| Format_Book_After_Signing | Whether to automatically format every book when it's signed |
|
| Format_Book_After_Signing | Whether to automatically format every book when it's signed |
|
||||||
| Change_Generation_On_Copy | Whether to display "COPY" or "COPY_OF_COPY" instead of "ORIGINAL" when a book is copied. This also uses the vanilla behavior where a copy of a copy or tattered book cannot be copied further. |
|
| Change_Generation_On_Copy | Whether to display "COPY" or "COPY_OF_COPY" instead of "ORIGINAL" when a book is copied. This also uses the vanilla behavior where a copy of a copy or tattered book cannot be copied further. |
|
||||||
|
| Enable_Book_Peeking | Whether to enable hitting a chiseled bookshelf while sneaking to see the shelf's contents. |
|
68
pom.xml
68
pom.xml
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<groupId>net.knarcraft</groupId>
|
<groupId>net.knarcraft</groupId>
|
||||||
<artifactId>BooksWithoutBorders</artifactId>
|
<artifactId>BooksWithoutBorders</artifactId>
|
||||||
<version>1.3.2</version>
|
<version>1.3.5</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<licenses>
|
<licenses>
|
||||||
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
<description>A continuation of the original Books Without Borders</description>
|
<description>A continuation of the original Books Without Borders</description>
|
||||||
<properties>
|
<properties>
|
||||||
<java.version>17</java.version>
|
<java.version>16</java.version>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
@ -31,14 +31,14 @@
|
|||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.8.1</version>
|
<version>3.8.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<source>17</source>
|
<source>${java.version}</source>
|
||||||
<target>17</target>
|
<target>${java.version}</target>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
<version>3.2.4</version>
|
<version>3.3.0</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<phase>package</phase>
|
<phase>package</phase>
|
||||||
@ -47,6 +47,30 @@
|
|||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||||
|
<relocations>
|
||||||
|
<relocation>
|
||||||
|
<pattern>net.knarcraft.knarlib</pattern>
|
||||||
|
<shadedPattern>net.knarcraft.bookswithoutborders.lib.knarlib</shadedPattern>
|
||||||
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>org.jetbrains.annotations</pattern>
|
||||||
|
<shadedPattern>net.knarcraft.bookswithoutborders.lib.annotations</shadedPattern>
|
||||||
|
</relocation>
|
||||||
|
</relocations>
|
||||||
|
<filters>
|
||||||
|
<filter>
|
||||||
|
<artifact>net.knarcraft:knarlib</artifact>
|
||||||
|
<includes>
|
||||||
|
<include>net/knarcraft/knarlib/**</include>
|
||||||
|
</includes>
|
||||||
|
</filter>
|
||||||
|
<filter>
|
||||||
|
<artifact>org.jetbrains:annotations</artifact>
|
||||||
|
<includes>
|
||||||
|
<include>org/jetbrains/annotations/**</include>
|
||||||
|
</includes>
|
||||||
|
</filter>
|
||||||
|
</filters>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
@ -61,6 +85,10 @@
|
|||||||
</build>
|
</build>
|
||||||
|
|
||||||
<repositories>
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>knarcraft-repo</id>
|
||||||
|
<url>https://git.knarcraft.net/api/packages/EpicKnarvik97/maven</url>
|
||||||
|
</repository>
|
||||||
<repository>
|
<repository>
|
||||||
<id>spigotmc-repo</id>
|
<id>spigotmc-repo</id>
|
||||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||||
@ -70,25 +98,47 @@
|
|||||||
<url>https://jitpack.io</url>
|
<url>https://jitpack.io</url>
|
||||||
</repository>
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
|
<distributionManagement>
|
||||||
|
<repository>
|
||||||
|
<id>knarcraft-repo</id>
|
||||||
|
<url>https://git.knarcraft.net/api/packages/EpicKnarvik97/maven</url>
|
||||||
|
</repository>
|
||||||
|
<snapshotRepository>
|
||||||
|
<id>knarcraft-repo</id>
|
||||||
|
<url>https://git.knarcraft.net/api/packages/EpicKnarvik97/maven</url>
|
||||||
|
</snapshotRepository>
|
||||||
|
</distributionManagement>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.spigotmc</groupId>
|
<groupId>org.spigotmc</groupId>
|
||||||
<artifactId>spigot-api</artifactId>
|
<artifactId>spigot-api</artifactId>
|
||||||
<version>1.19.2-R0.1-SNAPSHOT</version>
|
<version>1.21-R0.1-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.MilkBowl</groupId>
|
<groupId>com.github.MilkBowl</groupId>
|
||||||
<artifactId>VaultAPI</artifactId>
|
<artifactId>VaultAPI</artifactId>
|
||||||
<version>1.7</version>
|
<version>1.7.1</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.knarcraft</groupId>
|
||||||
|
<artifactId>knarlib</artifactId>
|
||||||
|
<version>1.2.7</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jetbrains</groupId>
|
<groupId>org.jetbrains</groupId>
|
||||||
<artifactId>annotations</artifactId>
|
<artifactId>annotations</artifactId>
|
||||||
<version>23.0.0</version>
|
<version>24.0.1</version>
|
||||||
<scope>provided</scope>
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.13.2</version>
|
||||||
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
@ -24,10 +24,11 @@ import net.knarcraft.bookswithoutborders.command.CommandSetTitle;
|
|||||||
import net.knarcraft.bookswithoutborders.command.CommandUnSign;
|
import net.knarcraft.bookswithoutborders.command.CommandUnSign;
|
||||||
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
||||||
import net.knarcraft.bookswithoutborders.listener.BookEventListener;
|
import net.knarcraft.bookswithoutborders.listener.BookEventListener;
|
||||||
|
import net.knarcraft.bookswithoutborders.listener.BookshelfListener;
|
||||||
import net.knarcraft.bookswithoutborders.listener.PlayerEventListener;
|
import net.knarcraft.bookswithoutborders.listener.PlayerEventListener;
|
||||||
import net.knarcraft.bookswithoutborders.listener.SignEventListener;
|
import net.knarcraft.bookswithoutborders.listener.SignEventListener;
|
||||||
import net.knarcraft.bookswithoutborders.utility.FileHelper;
|
import net.knarcraft.bookswithoutborders.utility.BookFileHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.UpdateChecker;
|
import net.knarcraft.knarlib.util.UpdateChecker;
|
||||||
import org.bukkit.command.CommandExecutor;
|
import org.bukkit.command.CommandExecutor;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.command.ConsoleCommandSender;
|
import org.bukkit.command.ConsoleCommandSender;
|
||||||
@ -45,6 +46,7 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getBookFolder;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getBookFolder;
|
||||||
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getErrorColor;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getErrorColor;
|
||||||
@ -84,7 +86,7 @@ public class BooksWithoutBorders extends JavaPlugin {
|
|||||||
} else if (sender instanceof Player player) {
|
} else if (sender instanceof Player player) {
|
||||||
UUID playerUUID = player.getUniqueId();
|
UUID playerUUID = player.getUniqueId();
|
||||||
if (!playerBooksList.containsKey(playerUUID)) {
|
if (!playerBooksList.containsKey(playerUUID)) {
|
||||||
List<String> newFiles = FileHelper.listFiles(sender, false);
|
List<String> newFiles = BookFileHelper.listFiles(sender, false);
|
||||||
playerBooksList.put(playerUUID, newFiles);
|
playerBooksList.put(playerUUID, newFiles);
|
||||||
}
|
}
|
||||||
return playerBooksList.get(playerUUID);
|
return playerBooksList.get(playerUUID);
|
||||||
@ -100,7 +102,7 @@ public class BooksWithoutBorders extends JavaPlugin {
|
|||||||
* @param updatePublic <p>Whether to update public books</p>
|
* @param updatePublic <p>Whether to update public books</p>
|
||||||
*/
|
*/
|
||||||
public static void updateBooks(CommandSender sender, boolean updatePublic) {
|
public static void updateBooks(CommandSender sender, boolean updatePublic) {
|
||||||
List<String> newFiles = FileHelper.listFiles(sender, updatePublic);
|
List<String> newFiles = BookFileHelper.listFiles(sender, updatePublic);
|
||||||
if (updatePublic) {
|
if (updatePublic) {
|
||||||
publicBooksList = newFiles;
|
publicBooksList = newFiles;
|
||||||
} else if (sender instanceof Player player) {
|
} else if (sender instanceof Player player) {
|
||||||
@ -122,7 +124,7 @@ public class BooksWithoutBorders extends JavaPlugin {
|
|||||||
consoleSender = this.getServer().getConsoleSender();
|
consoleSender = this.getServer().getConsoleSender();
|
||||||
playerBooksList = new HashMap<>();
|
playerBooksList = new HashMap<>();
|
||||||
BooksWithoutBordersConfig.initialize(this);
|
BooksWithoutBordersConfig.initialize(this);
|
||||||
publicBooksList = FileHelper.listFiles(consoleSender, true);
|
publicBooksList = BookFileHelper.listFiles(consoleSender, true);
|
||||||
|
|
||||||
PluginManager pluginManager = this.getServer().getPluginManager();
|
PluginManager pluginManager = this.getServer().getPluginManager();
|
||||||
|
|
||||||
@ -130,6 +132,7 @@ public class BooksWithoutBorders extends JavaPlugin {
|
|||||||
pluginManager.registerEvents(new PlayerEventListener(), this);
|
pluginManager.registerEvents(new PlayerEventListener(), this);
|
||||||
pluginManager.registerEvents(new SignEventListener(), this);
|
pluginManager.registerEvents(new SignEventListener(), this);
|
||||||
pluginManager.registerEvents(new BookEventListener(), this);
|
pluginManager.registerEvents(new BookEventListener(), this);
|
||||||
|
pluginManager.registerEvents(new BookshelfListener(), this);
|
||||||
} else {
|
} else {
|
||||||
this.getPluginLoader().disablePlugin(this);
|
this.getPluginLoader().disablePlugin(this);
|
||||||
}
|
}
|
||||||
@ -242,8 +245,8 @@ public class BooksWithoutBorders extends JavaPlugin {
|
|||||||
sendErrorMessage(consoleSender, "Saving failed! Aborting...");
|
sendErrorMessage(consoleSender, "Saving failed! Aborting...");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception exception) {
|
||||||
e.printStackTrace();
|
BooksWithoutBorders.getInstance().getLogger().log(Level.SEVERE, "Unable to create necessary folders");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -253,8 +256,8 @@ public class BooksWithoutBorders extends JavaPlugin {
|
|||||||
sendErrorMessage(consoleSender, "Saving failed! Aborting...");
|
sendErrorMessage(consoleSender, "Saving failed! Aborting...");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception exception) {
|
||||||
e.printStackTrace();
|
BooksWithoutBorders.getInstance().getLogger().log(Level.SEVERE, "Unable to create necessary folders");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,8 @@ import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
|||||||
import net.knarcraft.bookswithoutborders.utility.BookHelper;
|
import net.knarcraft.bookswithoutborders.utility.BookHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.EconomyHelper;
|
import net.knarcraft.bookswithoutborders.utility.EconomyHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
|
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.TabCompletionHelper;
|
import net.knarcraft.bookswithoutborders.utility.TabCompletionTypeHelper;
|
||||||
|
import net.knarcraft.knarlib.util.TabCompletionHelper;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
@ -142,7 +143,7 @@ public class CommandCopy implements TabExecutor {
|
|||||||
@NotNull String[] args) {
|
@NotNull String[] args) {
|
||||||
int argumentCount = args.length;
|
int argumentCount = args.length;
|
||||||
if (argumentCount == 1) {
|
if (argumentCount == 1) {
|
||||||
return TabCompletionHelper.filterMatchingStartsWith(TabCompletionHelper.getNumbers(1, 20), args[0]);
|
return TabCompletionHelper.filterMatchingStartsWith(TabCompletionTypeHelper.getNumbers(1, 20), args[0]);
|
||||||
}
|
}
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,9 @@ package net.knarcraft.bookswithoutborders.command;
|
|||||||
|
|
||||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
import net.knarcraft.bookswithoutborders.state.BookDirectory;
|
import net.knarcraft.bookswithoutborders.state.BookDirectory;
|
||||||
|
import net.knarcraft.bookswithoutborders.utility.BookFileHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.BookHelper;
|
import net.knarcraft.bookswithoutborders.utility.BookHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.FileHelper;
|
import net.knarcraft.knarlib.util.TabCompletionHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.TabCompletionHelper;
|
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.command.TabExecutor;
|
import org.bukkit.command.TabExecutor;
|
||||||
@ -41,7 +41,7 @@ public class CommandDelete implements TabExecutor {
|
|||||||
boolean deleteBook(CommandSender sender, String[] args, boolean deletePublic) {
|
boolean deleteBook(CommandSender sender, String[] args, boolean deletePublic) {
|
||||||
//List deletable files
|
//List deletable files
|
||||||
if (args.length == 0) {
|
if (args.length == 0) {
|
||||||
FileHelper.printBooks(sender, deletePublic);
|
BookFileHelper.printBooks(sender, deletePublic);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//Delete the file
|
//Delete the file
|
||||||
@ -82,7 +82,7 @@ public class CommandDelete implements TabExecutor {
|
|||||||
//Get the file to be deleted
|
//Get the file to be deleted
|
||||||
String bookDirectory = BookHelper.getBookDirectoryPathString(
|
String bookDirectory = BookHelper.getBookDirectoryPathString(
|
||||||
isPublic ? BookDirectory.PUBLIC : BookDirectory.PLAYER, sender);
|
isPublic ? BookDirectory.PUBLIC : BookDirectory.PLAYER, sender);
|
||||||
File file = FileHelper.getBookFile(bookDirectory + fileName);
|
File file = BookFileHelper.getBookFile(bookDirectory + fileName);
|
||||||
|
|
||||||
//Send message if no such file could be found
|
//Send message if no such file could be found
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
|
@ -5,7 +5,7 @@ import net.knarcraft.bookswithoutborders.state.EncryptionStyle;
|
|||||||
import net.knarcraft.bookswithoutborders.state.ItemSlot;
|
import net.knarcraft.bookswithoutborders.state.ItemSlot;
|
||||||
import net.knarcraft.bookswithoutborders.utility.EncryptionHelper;
|
import net.knarcraft.bookswithoutborders.utility.EncryptionHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
|
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.TabCompletionHelper;
|
import net.knarcraft.knarlib.util.TabCompletionHelper;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.command.TabExecutor;
|
import org.bukkit.command.TabExecutor;
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
package net.knarcraft.bookswithoutborders.command;
|
package net.knarcraft.bookswithoutborders.command;
|
||||||
|
|
||||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
|
import net.knarcraft.bookswithoutborders.utility.BookFileHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.BookLoader;
|
import net.knarcraft.bookswithoutborders.utility.BookLoader;
|
||||||
import net.knarcraft.bookswithoutborders.utility.FileHelper;
|
|
||||||
import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper;
|
import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.TabCompletionHelper;
|
import net.knarcraft.bookswithoutborders.utility.TabCompletionTypeHelper;
|
||||||
|
import net.knarcraft.knarlib.util.TabCompletionHelper;
|
||||||
import org.bukkit.Server;
|
import org.bukkit.Server;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
@ -49,7 +50,7 @@ public class CommandGive implements TabExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (args.length == 0) {
|
if (args.length == 0) {
|
||||||
FileHelper.printBooks(sender, givePublic);
|
BookFileHelper.printBooks(sender, givePublic);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,12 +133,12 @@ public class CommandGive implements TabExecutor {
|
|||||||
return null;
|
return null;
|
||||||
} else if (argumentCount == 3) {
|
} else if (argumentCount == 3) {
|
||||||
//Number of copies
|
//Number of copies
|
||||||
return TabCompletionHelper.filterMatchingStartsWith(TabCompletionHelper.getBooleansAndNumbers(1, 3), args[2]);
|
return TabCompletionHelper.filterMatchingStartsWith(TabCompletionTypeHelper.getBooleansAndNumbers(1, 3), args[2]);
|
||||||
} else if (argumentCount == 4) {
|
} else if (argumentCount == 4) {
|
||||||
//Signed
|
//Signed
|
||||||
try {
|
try {
|
||||||
Integer.parseInt(args[2]);
|
Integer.parseInt(args[2]);
|
||||||
return TabCompletionHelper.filterMatchingStartsWith(TabCompletionHelper.getBooleans(), args[3]);
|
return TabCompletionHelper.filterMatchingStartsWith(TabCompletionTypeHelper.getBooleans(), args[3]);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
package net.knarcraft.bookswithoutborders.command;
|
package net.knarcraft.bookswithoutborders.command;
|
||||||
|
|
||||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
|
import net.knarcraft.bookswithoutborders.utility.BookFileHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.BookLoader;
|
import net.knarcraft.bookswithoutborders.utility.BookLoader;
|
||||||
import net.knarcraft.bookswithoutborders.utility.FileHelper;
|
|
||||||
import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper;
|
import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.TabCompletionHelper;
|
import net.knarcraft.bookswithoutborders.utility.TabCompletionTypeHelper;
|
||||||
|
import net.knarcraft.knarlib.util.TabCompletionHelper;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.command.TabExecutor;
|
import org.bukkit.command.TabExecutor;
|
||||||
@ -49,7 +50,7 @@ public class CommandLoad implements TabExecutor {
|
|||||||
|
|
||||||
//Show books available to the player
|
//Show books available to the player
|
||||||
if (argumentCount == 0) {
|
if (argumentCount == 0) {
|
||||||
FileHelper.printBooks(sender, loadPublic);
|
BookFileHelper.printBooks(sender, loadPublic);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,12 +115,12 @@ public class CommandLoad implements TabExecutor {
|
|||||||
args[0]);
|
args[0]);
|
||||||
} else if (argumentCount == 2) {
|
} else if (argumentCount == 2) {
|
||||||
//Number of copies
|
//Number of copies
|
||||||
return TabCompletionHelper.filterMatchingStartsWith(TabCompletionHelper.getBooleansAndNumbers(1, 3), args[1]);
|
return TabCompletionHelper.filterMatchingStartsWith(TabCompletionTypeHelper.getBooleansAndNumbers(1, 3), args[1]);
|
||||||
} else if (argumentCount == 3) {
|
} else if (argumentCount == 3) {
|
||||||
//Signed
|
//Signed
|
||||||
try {
|
try {
|
||||||
Integer.parseInt(args[1]);
|
Integer.parseInt(args[1]);
|
||||||
return TabCompletionHelper.filterMatchingStartsWith(TabCompletionHelper.getBooleans(), args[2]);
|
return TabCompletionHelper.filterMatchingStartsWith(TabCompletionTypeHelper.getBooleans(), args[2]);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,9 @@ import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
|||||||
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
||||||
import net.knarcraft.bookswithoutborders.state.BookDirectory;
|
import net.knarcraft.bookswithoutborders.state.BookDirectory;
|
||||||
import net.knarcraft.bookswithoutborders.state.ItemSlot;
|
import net.knarcraft.bookswithoutborders.state.ItemSlot;
|
||||||
|
import net.knarcraft.bookswithoutborders.utility.BookFileHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.BookHelper;
|
import net.knarcraft.bookswithoutborders.utility.BookHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.BookToFromTextHelper;
|
import net.knarcraft.bookswithoutborders.utility.BookToFromTextHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.FileHelper;
|
|
||||||
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
|
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
@ -20,6 +20,7 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getCommandColor;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getCommandColor;
|
||||||
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getErrorColor;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getErrorColor;
|
||||||
@ -104,7 +105,7 @@ public class CommandSave implements TabExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Find any duplicates of the book
|
//Find any duplicates of the book
|
||||||
int foundDuplicates = FileHelper.findDuplicates(foundFiles, fileName);
|
int foundDuplicates = BookFileHelper.findDuplicates(foundFiles, fileName);
|
||||||
|
|
||||||
//Deal with duplicates
|
//Deal with duplicates
|
||||||
if (foundDuplicates > 0) {
|
if (foundDuplicates > 0) {
|
||||||
@ -142,8 +143,8 @@ public class CommandSave implements TabExecutor {
|
|||||||
//Update the relevant book list
|
//Update the relevant book list
|
||||||
BooksWithoutBorders.updateBooks(player, saveToPublicFolder);
|
BooksWithoutBorders.updateBooks(player, saveToPublicFolder);
|
||||||
BooksWithoutBorders.sendSuccessMessage(player, "Book Saved as \"" + fileName + "\"");
|
BooksWithoutBorders.sendSuccessMessage(player, "Book Saved as \"" + fileName + "\"");
|
||||||
} catch (IOException e) {
|
} catch (IOException exception) {
|
||||||
e.printStackTrace();
|
BooksWithoutBorders.getInstance().getLogger().log(Level.SEVERE, "Unable to save book");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,8 @@ import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
|||||||
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
||||||
import net.knarcraft.bookswithoutborders.utility.EconomyHelper;
|
import net.knarcraft.bookswithoutborders.utility.EconomyHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
|
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.TabCompletionHelper;
|
import net.knarcraft.bookswithoutborders.utility.TabCompletionTypeHelper;
|
||||||
|
import net.knarcraft.knarlib.util.TabCompletionHelper;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
@ -144,7 +145,7 @@ public class CommandSetBookPrice implements TabExecutor {
|
|||||||
if (argumentCount == 1) {
|
if (argumentCount == 1) {
|
||||||
return TabCompletionHelper.filterMatchingStartsWith(paymentTypes, args[0]);
|
return TabCompletionHelper.filterMatchingStartsWith(paymentTypes, args[0]);
|
||||||
} else if (argumentCount == 2) {
|
} else if (argumentCount == 2) {
|
||||||
return TabCompletionHelper.filterMatchingStartsWith(TabCompletionHelper.getNumbers(1, 3), args[1]);
|
return TabCompletionHelper.filterMatchingStartsWith(TabCompletionTypeHelper.getNumbers(1, 3), args[1]);
|
||||||
}
|
}
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,9 @@ package net.knarcraft.bookswithoutborders.command;
|
|||||||
|
|
||||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
||||||
import net.knarcraft.bookswithoutborders.utility.BookFormatter;
|
|
||||||
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
|
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
|
||||||
|
import net.knarcraft.knarlib.property.ColorConversion;
|
||||||
|
import net.knarcraft.knarlib.util.ColorHelper;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
@ -44,7 +45,7 @@ public class CommandSetLore implements TabExecutor {
|
|||||||
String rawLore = String.join(" ", args);
|
String rawLore = String.join(" ", args);
|
||||||
|
|
||||||
//Format lore
|
//Format lore
|
||||||
rawLore = BookFormatter.translateAllColorCodes(rawLore);
|
rawLore = ColorHelper.translateColorCodes(rawLore, ColorConversion.RGB);
|
||||||
String[] loreParts = rawLore.split(BooksWithoutBordersConfig.getLoreSeparator());
|
String[] loreParts = rawLore.split(BooksWithoutBordersConfig.getLoreSeparator());
|
||||||
List<String> newLore = new ArrayList<>(Arrays.asList(loreParts));
|
List<String> newLore = new ArrayList<>(Arrays.asList(loreParts));
|
||||||
|
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
package net.knarcraft.bookswithoutborders.command;
|
package net.knarcraft.bookswithoutborders.command;
|
||||||
|
|
||||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
import net.knarcraft.bookswithoutborders.utility.BookFormatter;
|
|
||||||
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
|
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
|
||||||
|
import net.knarcraft.knarlib.property.ColorConversion;
|
||||||
|
import net.knarcraft.knarlib.util.ColorHelper;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
@ -41,7 +42,7 @@ public class CommandSetTitle implements TabExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String title = String.join(" ", args);
|
String title = String.join(" ", args);
|
||||||
title = BookFormatter.translateAllColorCodes(title);
|
title = ColorHelper.translateColorCodes(title, ColorConversion.RGB);
|
||||||
|
|
||||||
ItemMeta itemMetadata = heldItem.getItemMeta();
|
ItemMeta itemMetadata = heldItem.getItemMeta();
|
||||||
if (itemMetadata == null) {
|
if (itemMetadata == null) {
|
||||||
|
@ -12,11 +12,13 @@ import org.bukkit.command.TabExecutor;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.BookMeta;
|
import org.bukkit.inventory.meta.BookMeta;
|
||||||
|
import org.bukkit.inventory.meta.WritableBookMeta;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Command executor for the unsign command
|
* Command executor for the unsign command
|
||||||
@ -49,21 +51,36 @@ public class CommandUnSign implements TabExecutor {
|
|||||||
*/
|
*/
|
||||||
public void unSignHeldBook(Player player, boolean mainHand) {
|
public void unSignHeldBook(Player player, boolean mainHand) {
|
||||||
//Get the old book
|
//Get the old book
|
||||||
BookMeta oldBook = InventoryHelper.getHeldBookMetadata(player, mainHand);
|
BookMeta oldMetadata = InventoryHelper.getHeldBookMetadata(player, mainHand);
|
||||||
ItemStack heldBook = InventoryHelper.getHeldBook(player, mainHand);
|
ItemStack heldBook = InventoryHelper.getHeldBook(player, mainHand);
|
||||||
|
|
||||||
//Only allow the owner to un-sign the book
|
//Only allow the owner to un-sign the book
|
||||||
if (BooksWithoutBordersConfig.getAuthorOnlyUnsign() && !player.hasPermission("bookswithoutborders.bypassAuthorOnlyUnsign")) {
|
if (BooksWithoutBordersConfig.getAuthorOnlyUnsign() && !player.hasPermission("bookswithoutborders.bypassAuthorOnlyUnsign")) {
|
||||||
if (BookHelper.isNotAuthor(player, Objects.requireNonNull(oldBook))) {
|
if (BookHelper.isNotAuthor(player, Objects.requireNonNull(oldMetadata))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//UnSign the book
|
WritableBookMeta newMetadata = (BookMeta) BooksWithoutBorders.getItemFactory().getItemMeta(Material.WRITABLE_BOOK);
|
||||||
ItemStack newBook = new ItemStack(Material.WRITABLE_BOOK);
|
if (newMetadata == null) {
|
||||||
newBook.setAmount(heldBook.getAmount());
|
BooksWithoutBorders.getInstance().getLogger().log(Level.SEVERE, "Unable to create writable book metadata");
|
||||||
newBook.setItemMeta(oldBook);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Create a new unsigned book with the same data
|
||||||
|
ItemStack newBook = new ItemStack(Material.WRITABLE_BOOK, heldBook.getAmount());
|
||||||
|
if (oldMetadata.hasLore()) {
|
||||||
|
List<String> oldLore = oldMetadata.getLore();
|
||||||
|
if (oldLore != null) {
|
||||||
|
List<String> newLore = new ArrayList<>(oldLore);
|
||||||
|
newLore.remove(0);
|
||||||
|
newMetadata.setLore(newLore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newMetadata.setPages(oldMetadata.getPages());
|
||||||
|
newBook.setItemMeta(newMetadata);
|
||||||
|
|
||||||
|
// Give the player the new book
|
||||||
InventoryHelper.replaceHeldItem(player, newBook, mainHand);
|
InventoryHelper.replaceHeldItem(player, newBook, mainHand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import org.bukkit.Material;
|
|||||||
import org.bukkit.command.ConsoleCommandSender;
|
import org.bukkit.command.ConsoleCommandSender;
|
||||||
import org.bukkit.configuration.Configuration;
|
import org.bukkit.configuration.Configuration;
|
||||||
|
|
||||||
|
import java.nio.file.FileSystems;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -22,7 +23,7 @@ public class BooksWithoutBordersConfig {
|
|||||||
private static final ChatColor errorColor = ChatColor.RED;
|
private static final ChatColor errorColor = ChatColor.RED;
|
||||||
private static final ChatColor successColor = ChatColor.GREEN;
|
private static final ChatColor successColor = ChatColor.GREEN;
|
||||||
private static final ChatColor commandColor = ChatColor.YELLOW;
|
private static final ChatColor commandColor = ChatColor.YELLOW;
|
||||||
private static final String SLASH = System.getProperty("file.separator");
|
private static final String SLASH = FileSystems.getDefault().getSeparator();
|
||||||
private static boolean isInitialized;
|
private static boolean isInitialized;
|
||||||
public static String bookFolder;
|
public static String bookFolder;
|
||||||
|
|
||||||
@ -40,6 +41,7 @@ public class BooksWithoutBordersConfig {
|
|||||||
private static boolean adminDecrypt;
|
private static boolean adminDecrypt;
|
||||||
private static boolean formatBooks;
|
private static boolean formatBooks;
|
||||||
private static boolean changeGenerationOnCopy;
|
private static boolean changeGenerationOnCopy;
|
||||||
|
private static boolean enableBookshelfPeeking;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the books without borders settings class
|
* Initializes the books without borders settings class
|
||||||
@ -127,6 +129,15 @@ public class BooksWithoutBordersConfig {
|
|||||||
return authorOnlySave;
|
return authorOnlySave;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether players can left-click a bookshelf to peek at the contained books
|
||||||
|
*
|
||||||
|
* @return <p>True if players can peek at the contained books</p>
|
||||||
|
*/
|
||||||
|
public static boolean getEnableBookshelfPeeking() {
|
||||||
|
return enableBookshelfPeeking;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets whether to use YML, not TXT, for saving books
|
* Gets whether to use YML, not TXT, for saving books
|
||||||
*
|
*
|
||||||
@ -272,6 +283,7 @@ public class BooksWithoutBordersConfig {
|
|||||||
config.set(ConfigOption.BOOKS_FOR_NEW_PLAYERS.getConfigNode(), firstBooks);
|
config.set(ConfigOption.BOOKS_FOR_NEW_PLAYERS.getConfigNode(), firstBooks);
|
||||||
config.set(ConfigOption.MESSAGE_FOR_NEW_PLAYERS.getConfigNode(), welcomeMessage);
|
config.set(ConfigOption.MESSAGE_FOR_NEW_PLAYERS.getConfigNode(), welcomeMessage);
|
||||||
config.set(ConfigOption.FORMAT_AFTER_SIGNING.getConfigNode(), formatBooks);
|
config.set(ConfigOption.FORMAT_AFTER_SIGNING.getConfigNode(), formatBooks);
|
||||||
|
config.set(ConfigOption.ENABLE_BOOKSHELF_PEEKING.getConfigNode(), enableBookshelfPeeking);
|
||||||
|
|
||||||
String itemTypeNode = ConfigOption.PRICE_ITEM_TYPE.getConfigNode();
|
String itemTypeNode = ConfigOption.PRICE_ITEM_TYPE.getConfigNode();
|
||||||
if (bookPriceType != null) {
|
if (bookPriceType != null) {
|
||||||
@ -319,7 +331,8 @@ public class BooksWithoutBordersConfig {
|
|||||||
Configuration config = BooksWithoutBorders.getInstance().getConfig();
|
Configuration config = BooksWithoutBorders.getInstance().getConfig();
|
||||||
try {
|
try {
|
||||||
useYml = getBoolean(config, ConfigOption.USE_YAML);
|
useYml = getBoolean(config, ConfigOption.USE_YAML);
|
||||||
bookDuplicateLimit = getInt(config, ConfigOption.MAX_DUPLICATES);
|
bookDuplicateLimit = config.getInt(ConfigOption.MAX_DUPLICATES.getConfigNode(),
|
||||||
|
(Integer) ConfigOption.MAX_DUPLICATES.getDefaultValue());
|
||||||
titleAuthorSeparator = getString(config, ConfigOption.TITLE_AUTHOR_SEPARATOR);
|
titleAuthorSeparator = getString(config, ConfigOption.TITLE_AUTHOR_SEPARATOR);
|
||||||
loreSeparator = getString(config, ConfigOption.LORE_LINE_SEPARATOR);
|
loreSeparator = getString(config, ConfigOption.LORE_LINE_SEPARATOR);
|
||||||
adminDecrypt = getBoolean(config, ConfigOption.ADMIN_AUTO_DECRYPT);
|
adminDecrypt = getBoolean(config, ConfigOption.ADMIN_AUTO_DECRYPT);
|
||||||
@ -330,6 +343,7 @@ public class BooksWithoutBordersConfig {
|
|||||||
welcomeMessage = getString(config, ConfigOption.MESSAGE_FOR_NEW_PLAYERS);
|
welcomeMessage = getString(config, ConfigOption.MESSAGE_FOR_NEW_PLAYERS);
|
||||||
formatBooks = getBoolean(config, ConfigOption.FORMAT_AFTER_SIGNING);
|
formatBooks = getBoolean(config, ConfigOption.FORMAT_AFTER_SIGNING);
|
||||||
changeGenerationOnCopy = getBoolean(config, ConfigOption.CHANGE_GENERATION_ON_COPY);
|
changeGenerationOnCopy = getBoolean(config, ConfigOption.CHANGE_GENERATION_ON_COPY);
|
||||||
|
enableBookshelfPeeking = getBoolean(config, ConfigOption.ENABLE_BOOKSHELF_PEEKING);
|
||||||
|
|
||||||
//Convert string into material
|
//Convert string into material
|
||||||
String paymentMaterial = getString(config, ConfigOption.PRICE_ITEM_TYPE);
|
String paymentMaterial = getString(config, ConfigOption.PRICE_ITEM_TYPE);
|
||||||
@ -347,7 +361,8 @@ public class BooksWithoutBordersConfig {
|
|||||||
bookPriceType = material;
|
bookPriceType = material;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bookPriceQuantity = getDouble(config, ConfigOption.PRICE_QUANTITY);
|
bookPriceQuantity = config.getDouble(ConfigOption.PRICE_QUANTITY.getConfigNode(),
|
||||||
|
(Double) ConfigOption.PRICE_QUANTITY.getDefaultValue());
|
||||||
|
|
||||||
//Make sure titleAuthorSeparator is a valid value
|
//Make sure titleAuthorSeparator is a valid value
|
||||||
titleAuthorSeparator = cleanString(titleAuthorSeparator);
|
titleAuthorSeparator = cleanString(titleAuthorSeparator);
|
||||||
@ -366,28 +381,6 @@ public class BooksWithoutBordersConfig {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the double value of the given config option
|
|
||||||
*
|
|
||||||
* @param config <p>The configuration to read from</p>
|
|
||||||
* @param configOption <p>The configuration option to get the value for</p>
|
|
||||||
* @return <p>The value of the option</p>
|
|
||||||
*/
|
|
||||||
private static double getDouble(Configuration config, ConfigOption configOption) {
|
|
||||||
return config.getDouble(configOption.getConfigNode(), (Double) configOption.getDefaultValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the integer value of the given config option
|
|
||||||
*
|
|
||||||
* @param config <p>The configuration to read from</p>
|
|
||||||
* @param configOption <p>The configuration option to get the value for</p>
|
|
||||||
* @return <p>The value of the option</p>
|
|
||||||
*/
|
|
||||||
private static int getInt(Configuration config, ConfigOption configOption) {
|
|
||||||
return config.getInt(configOption.getConfigNode(), (Integer) configOption.getDefaultValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the string value of the given config option
|
* Gets the string value of the given config option
|
||||||
*
|
*
|
||||||
|
@ -73,7 +73,13 @@ public enum ConfigOption {
|
|||||||
/**
|
/**
|
||||||
* Whether to automatically format every signed book
|
* Whether to automatically format every signed book
|
||||||
*/
|
*/
|
||||||
FORMAT_AFTER_SIGNING("Options.Format_Book_After_Signing", false);
|
FORMAT_AFTER_SIGNING("Options.Format_Book_After_Signing", false),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether hitting a bookshelf should display information about the contained books
|
||||||
|
*/
|
||||||
|
ENABLE_BOOKSHELF_PEEKING("Options.Enable_Book_Peeking", false),
|
||||||
|
;
|
||||||
|
|
||||||
private final String configNode;
|
private final String configNode;
|
||||||
private final Object defaultValue;
|
private final Object defaultValue;
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package net.knarcraft.bookswithoutborders.encryption;
|
package net.knarcraft.bookswithoutborders.encryption;
|
||||||
|
|
||||||
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
|
|
||||||
import javax.crypto.BadPaddingException;
|
import javax.crypto.BadPaddingException;
|
||||||
import javax.crypto.Cipher;
|
import javax.crypto.Cipher;
|
||||||
import javax.crypto.IllegalBlockSizeException;
|
import javax.crypto.IllegalBlockSizeException;
|
||||||
@ -15,6 +17,7 @@ import java.security.NoSuchAlgorithmException;
|
|||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.security.spec.InvalidKeySpecException;
|
import java.security.spec.InvalidKeySpecException;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class represents and AES encryptor/decryptor
|
* This class represents and AES encryptor/decryptor
|
||||||
@ -66,16 +69,16 @@ public class AES {
|
|||||||
//Initialize cipher
|
//Initialize cipher
|
||||||
try {
|
try {
|
||||||
aes.init(mode, secretKeySpec, ivParameterSpec);
|
aes.init(mode, secretKeySpec, ivParameterSpec);
|
||||||
} catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
|
} catch (InvalidKeyException | InvalidAlgorithmParameterException exception) {
|
||||||
e.printStackTrace();
|
BooksWithoutBorders.getInstance().getLogger().log(Level.SEVERE, "Invalid AES input given!");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
//Perform encryption/decryption and output result
|
//Perform encryption/decryption and output result
|
||||||
try {
|
try {
|
||||||
byte[] output = aes.doFinal(getInputBytes(input, encrypt));
|
byte[] output = aes.doFinal(getInputBytes(input, encrypt));
|
||||||
return createResult(output, encrypt);
|
return createResult(output, encrypt);
|
||||||
} catch (IllegalBlockSizeException | BadPaddingException e) {
|
} catch (IllegalBlockSizeException | BadPaddingException exception) {
|
||||||
e.printStackTrace();
|
BooksWithoutBorders.getInstance().getLogger().log(Level.SEVERE, "Invalid AES block size or padding");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -131,8 +134,8 @@ public class AES {
|
|||||||
Cipher aes;
|
Cipher aes;
|
||||||
try {
|
try {
|
||||||
aes = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
aes = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||||
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
|
} catch (NoSuchAlgorithmException | NoSuchPaddingException exception) {
|
||||||
e.printStackTrace();
|
BooksWithoutBorders.getInstance().getLogger().log(Level.SEVERE, "Invalid AES algorithm or padding");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return aes;
|
return aes;
|
||||||
@ -149,15 +152,15 @@ public class AES {
|
|||||||
SecretKeyFactory keyFactory;
|
SecretKeyFactory keyFactory;
|
||||||
try {
|
try {
|
||||||
keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
|
keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
|
||||||
} catch (NoSuchAlgorithmException e) {
|
} catch (NoSuchAlgorithmException exception) {
|
||||||
e.printStackTrace();
|
BooksWithoutBorders.getInstance().getLogger().log(Level.SEVERE, "Invalid AES algorithm");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
SecretKey tmp;
|
SecretKey tmp;
|
||||||
try {
|
try {
|
||||||
tmp = keyFactory.generateSecret(spec);
|
tmp = keyFactory.generateSecret(spec);
|
||||||
} catch (InvalidKeySpecException e) {
|
} catch (InvalidKeySpecException exception) {
|
||||||
e.printStackTrace();
|
BooksWithoutBorders.getInstance().getLogger().log(Level.SEVERE, "Invalid AES key specification");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new SecretKeySpec(tmp.getEncoded(), "AES");
|
return new SecretKeySpec(tmp.getEncoded(), "AES");
|
||||||
|
@ -33,7 +33,7 @@ public class GenenCrypt {
|
|||||||
for (int j = 0; j < 4; j++) {
|
for (int j = 0; j < 4; j++) {
|
||||||
for (int k = 0; k < 4; k++) {
|
for (int k = 0; k < 4; k++) {
|
||||||
for (int l = 0; l < 4; l++) {
|
for (int l = 0; l < 4; l++) {
|
||||||
originalCodonList.add("" + bases[i] + bases[j] + bases[k] + bases[l]);
|
originalCodonList.add(bases[i] + bases[j] + bases[k] + bases[l]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -49,7 +49,7 @@ public class GenenCrypt {
|
|||||||
|
|
||||||
// use the random number generator and the originalCodonList to make a shuffled list
|
// use the random number generator and the originalCodonList to make a shuffled list
|
||||||
ArrayList<String> shuffledCodonList = new ArrayList<>();
|
ArrayList<String> shuffledCodonList = new ArrayList<>();
|
||||||
while (originalCodonList.size() > 0) {
|
while (!originalCodonList.isEmpty()) {
|
||||||
int index = ranGen.nextInt(originalCodonList.size());
|
int index = ranGen.nextInt(originalCodonList.size());
|
||||||
shuffledCodonList.add(originalCodonList.get(index));
|
shuffledCodonList.add(originalCodonList.get(index));
|
||||||
originalCodonList.remove(index);
|
originalCodonList.remove(index);
|
||||||
@ -97,9 +97,12 @@ public class GenenCrypt {
|
|||||||
String s = charList[i];
|
String s = charList[i];
|
||||||
String[] sa = codonTable.get(s);
|
String[] sa = codonTable.get(s);
|
||||||
switch (s) {
|
switch (s) {
|
||||||
case "\t" -> System.out.println(i + "\t" + "\\t" + "\t" + sa[0] + ", " + sa[1] + ", " + sa[2] + ", " + sa[3]);
|
case "\t" ->
|
||||||
case "\n" -> System.out.println(i + "\t" + "\\n" + "\t" + sa[0] + ", " + sa[1] + ", " + sa[2] + ", " + sa[3]);
|
System.out.println(i + "\t" + "\\t" + "\t" + sa[0] + ", " + sa[1] + ", " + sa[2] + ", " + sa[3]);
|
||||||
case " " -> System.out.println(i + "\t" + "\" \"" + "\t" + sa[0] + ", " + sa[1] + ", " + sa[2] + ", " + sa[3]);
|
case "\n" ->
|
||||||
|
System.out.println(i + "\t" + "\\n" + "\t" + sa[0] + ", " + sa[1] + ", " + sa[2] + ", " + sa[3]);
|
||||||
|
case " " ->
|
||||||
|
System.out.println(i + "\t" + "\" \"" + "\t" + sa[0] + ", " + sa[1] + ", " + sa[2] + ", " + sa[3]);
|
||||||
default -> System.out.println(i + "\t" + s + "\t" + sa[0] + ", " + sa[1] + ", " + sa[2] + ", " + sa[3]);
|
default -> System.out.println(i + "\t" + s + "\t" + sa[0] + ", " + sa[1] + ", " + sa[2] + ", " + sa[3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ public class SubstitutionCipher {
|
|||||||
// original message is offset by
|
// original message is offset by
|
||||||
public String encrypt(String in, String key) {
|
public String encrypt(String in, String key) {
|
||||||
StringBuilder output = new StringBuilder();
|
StringBuilder output = new StringBuilder();
|
||||||
if (key != null && key.length() > 0) {
|
if (key != null && !key.isEmpty()) {
|
||||||
StringTokenizer tokenizer = new StringTokenizer(key, ", "); // tokenizes the key
|
StringTokenizer tokenizer = new StringTokenizer(key, ", "); // tokenizes the key
|
||||||
// converts each number in the key to an integer and adds to an array
|
// converts each number in the key to an integer and adds to an array
|
||||||
int[] offsetArray = new int[tokenizer.countTokens()];
|
int[] offsetArray = new int[tokenizer.countTokens()];
|
||||||
@ -52,9 +52,10 @@ public class SubstitutionCipher {
|
|||||||
// but in reverse. Could probably be combined into one
|
// but in reverse. Could probably be combined into one
|
||||||
// method with a flag for encryption / decryption, but
|
// method with a flag for encryption / decryption, but
|
||||||
// I'm lazy.
|
// I'm lazy.
|
||||||
|
@SuppressWarnings("unused")
|
||||||
public String decrypt(String in, String key) {
|
public String decrypt(String in, String key) {
|
||||||
StringBuilder output = new StringBuilder();
|
StringBuilder output = new StringBuilder();
|
||||||
if (key != null && key.length() > 0) {
|
if (key != null && !key.isEmpty()) {
|
||||||
StringTokenizer tokenizer = new StringTokenizer(key, ", "); // tokenizes the key
|
StringTokenizer tokenizer = new StringTokenizer(key, ", "); // tokenizes the key
|
||||||
// converts each number in the key to an integer and adds to an array
|
// converts each number in the key to an integer and adds to an array
|
||||||
int[] offsetArray = new int[tokenizer.countTokens()];
|
int[] offsetArray = new int[tokenizer.countTokens()];
|
||||||
@ -79,6 +80,7 @@ public class SubstitutionCipher {
|
|||||||
// the one time pad encryption is very secure, and
|
// the one time pad encryption is very secure, and
|
||||||
// encryption works just like decryption, but is
|
// encryption works just like decryption, but is
|
||||||
// vulnerable if the same key is used more than once.
|
// vulnerable if the same key is used more than once.
|
||||||
|
@SuppressWarnings("unused")
|
||||||
public String oneTimePad(String in, String key) {
|
public String oneTimePad(String in, String key) {
|
||||||
StringBuilder output = new StringBuilder();
|
StringBuilder output = new StringBuilder();
|
||||||
for (int i = 0; i < in.length(); i++) {
|
for (int i = 0; i < in.length(); i++) {
|
||||||
|
@ -0,0 +1,160 @@
|
|||||||
|
package net.knarcraft.bookswithoutborders.listener;
|
||||||
|
|
||||||
|
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
||||||
|
import net.knarcraft.bookswithoutborders.utility.IntegerToRomanConverter;
|
||||||
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
import org.bukkit.block.ChiseledBookshelf;
|
||||||
|
import org.bukkit.enchantments.Enchantment;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.block.Action;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
import org.bukkit.inventory.ChiseledBookshelfInventory;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.BookMeta;
|
||||||
|
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getSuccessColor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A listener for bookshelf clicking
|
||||||
|
*/
|
||||||
|
public class BookshelfListener implements Listener {
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onBookshelfClick(PlayerInteractEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
|
||||||
|
// If left-clicking a chiseled bookshelf and sneaking, display contents
|
||||||
|
if (!event.hasBlock() || event.getClickedBlock() == null ||
|
||||||
|
!(event.getClickedBlock().getState() instanceof ChiseledBookshelf chiseledBookshelf) ||
|
||||||
|
event.getAction() != Action.LEFT_CLICK_BLOCK || !player.isSneaking()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if bookshelf peeking is enabled, and the player can peek
|
||||||
|
if (!BooksWithoutBordersConfig.getEnableBookshelfPeeking() ||
|
||||||
|
!event.getPlayer().hasPermission("bookswithoutborders.peekbookshelf")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.setUseInteractedBlock(Event.Result.DENY);
|
||||||
|
event.setUseItemInHand(Event.Result.DENY);
|
||||||
|
|
||||||
|
ChiseledBookshelfInventory bookshelfInventory = chiseledBookshelf.getInventory();
|
||||||
|
player.sendMessage(getBookshelfDescription(bookshelfInventory));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the description for a bookshelf's contents
|
||||||
|
*
|
||||||
|
* @param bookshelfInventory <p>The inventory of the bookshelf to describe</p>
|
||||||
|
* @return <p>A textual description of the bookshelf's contents</p>
|
||||||
|
*/
|
||||||
|
private String getBookshelfDescription(ChiseledBookshelfInventory bookshelfInventory) {
|
||||||
|
StringBuilder builder = new StringBuilder(getSuccessColor() + "Books in shelf:");
|
||||||
|
for (ItemStack itemStack : bookshelfInventory.getStorageContents()) {
|
||||||
|
if (itemStack == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ItemMeta meta = itemStack.getItemMeta();
|
||||||
|
builder.append("\n ").append(ChatColor.GRAY).append(" - ");
|
||||||
|
if (meta instanceof BookMeta bookMeta) {
|
||||||
|
builder.append(getBookDescription(bookMeta));
|
||||||
|
} else if (meta instanceof EnchantmentStorageMeta enchantmentStorageMeta) {
|
||||||
|
builder.append(getEnchantedBookDescription(enchantmentStorageMeta));
|
||||||
|
} else if (meta != null) {
|
||||||
|
builder.append(getPlainBookDescription(meta));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the description of a plain (enchant-able) book
|
||||||
|
*
|
||||||
|
* @param itemMeta <p>The metadata for the book to describe</p>
|
||||||
|
* @return <p>The description of the book</p>
|
||||||
|
*/
|
||||||
|
private String getPlainBookDescription(ItemMeta itemMeta) {
|
||||||
|
String name = itemMeta.getDisplayName();
|
||||||
|
if (name.isEmpty()) {
|
||||||
|
name = "Plain book";
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the description of a book
|
||||||
|
*
|
||||||
|
* @param bookMeta <p>The metadata for the book to describe</p>
|
||||||
|
* @return <p>The book's description</p>
|
||||||
|
*/
|
||||||
|
private String getBookDescription(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 = "Unknown";
|
||||||
|
} else {
|
||||||
|
author = bookMeta.getAuthor();
|
||||||
|
}
|
||||||
|
return title + " by " + author;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the description of an enchanted book
|
||||||
|
*
|
||||||
|
* @param enchantmentStorageMeta <p>The metadata for the enchanted book to describe</p>
|
||||||
|
* @return <p>The enchanted book's description</p>
|
||||||
|
*/
|
||||||
|
private String getEnchantedBookDescription(EnchantmentStorageMeta enchantmentStorageMeta) {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("Enchanted book (");
|
||||||
|
Map<Enchantment, Integer> enchantmentMap = enchantmentStorageMeta.getStoredEnchants();
|
||||||
|
List<String> enchantments = new ArrayList<>(enchantmentMap.size());
|
||||||
|
for (Map.Entry<Enchantment, Integer> enchantmentEntry : enchantmentMap.entrySet()) {
|
||||||
|
enchantments.add(getEnchantmentName(enchantmentEntry.getKey()) + " " +
|
||||||
|
IntegerToRomanConverter.getRomanNumber(enchantmentEntry.getValue()));
|
||||||
|
}
|
||||||
|
builder.append(String.join(", ", enchantments));
|
||||||
|
builder.append(")");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a prettified name of an enchantment
|
||||||
|
*
|
||||||
|
* @param enchantment <p>The enchantment to get the name of</p>
|
||||||
|
* @return <p>The prettified enchantment name</p>
|
||||||
|
*/
|
||||||
|
private String getEnchantmentName(Enchantment enchantment) {
|
||||||
|
return uppercaseFirst(enchantment.getKey().getKey().replace("_", " "));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turns the first character of each of a string's words into uppercase
|
||||||
|
*
|
||||||
|
* @param input <p>The input to uppercase</p>
|
||||||
|
* @return <p>The input string with more uppercase</p>
|
||||||
|
*/
|
||||||
|
private String uppercaseFirst(String input) {
|
||||||
|
String[] parts = input.split(" ");
|
||||||
|
for (int i = 0; i < parts.length; i++) {
|
||||||
|
parts[i] = parts[i].substring(0, 1).toUpperCase() + parts[i].substring(1);
|
||||||
|
}
|
||||||
|
return String.join(" ", parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -3,14 +3,16 @@ package net.knarcraft.bookswithoutborders.listener;
|
|||||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
||||||
import net.knarcraft.bookswithoutborders.state.EncryptionStyle;
|
import net.knarcraft.bookswithoutborders.state.EncryptionStyle;
|
||||||
|
import net.knarcraft.bookswithoutborders.utility.BookFileHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.BookLoader;
|
import net.knarcraft.bookswithoutborders.utility.BookLoader;
|
||||||
import net.knarcraft.bookswithoutborders.utility.EncryptionHelper;
|
import net.knarcraft.bookswithoutborders.utility.EncryptionHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.FileHelper;
|
|
||||||
import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper;
|
import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper;
|
||||||
import net.md_5.bungee.api.ChatColor;
|
import net.md_5.bungee.api.ChatColor;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Tag;
|
import org.bukkit.Tag;
|
||||||
import org.bukkit.block.Sign;
|
import org.bukkit.block.Sign;
|
||||||
|
import org.bukkit.block.sign.Side;
|
||||||
|
import org.bukkit.block.sign.SignSide;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.Event;
|
import org.bukkit.event.Event;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
@ -27,7 +29,7 @@ import java.io.File;
|
|||||||
|
|
||||||
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getBookFolder;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getBookFolder;
|
||||||
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getSlash;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getSlash;
|
||||||
import static net.knarcraft.bookswithoutborders.utility.FileHelper.isBookListIndex;
|
import static net.knarcraft.bookswithoutborders.utility.BookFileHelper.isBookListIndex;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A listener for relevant sign events such as clicking a decryption sign
|
* A listener for relevant sign events such as clicking a decryption sign
|
||||||
@ -55,7 +57,7 @@ public class SignEventListener implements Listener {
|
|||||||
|
|
||||||
//Check if the sign is of a valid type
|
//Check if the sign is of a valid type
|
||||||
if (!((lines[1].equalsIgnoreCase("[Encrypt]") || lines[1].equalsIgnoreCase("[Decrypt]") ||
|
if (!((lines[1].equalsIgnoreCase("[Encrypt]") || lines[1].equalsIgnoreCase("[Decrypt]") ||
|
||||||
lines[1].equalsIgnoreCase("[Give]")) && lines[2].trim().length() > 0)) {
|
lines[1].equalsIgnoreCase("[Give]")) && !lines[2].trim().isEmpty())) {
|
||||||
//Mark the second line as invalid
|
//Mark the second line as invalid
|
||||||
event.setLine(1, ChatColor.DARK_RED + lines[1]);
|
event.setLine(1, ChatColor.DARK_RED + lines[1]);
|
||||||
return;
|
return;
|
||||||
@ -100,7 +102,10 @@ public class SignEventListener implements Listener {
|
|||||||
event.setUseItemInHand(Event.Result.DENY);
|
event.setUseItemInHand(Event.Result.DENY);
|
||||||
//The player right-clicked a sign
|
//The player right-clicked a sign
|
||||||
Sign sign = (Sign) event.getClickedBlock().getState();
|
Sign sign = (Sign) event.getClickedBlock().getState();
|
||||||
if (signLineEquals(sign, 0, "[BwB]", ChatColor.DARK_GREEN)) {
|
if (!signLineEquals(sign, 0, "[BwB]", ChatColor.DARK_GREEN)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (signLineEquals(sign, 1, "[Encrypt]", ChatColor.DARK_BLUE)) {
|
if (signLineEquals(sign, 1, "[Encrypt]", ChatColor.DARK_BLUE)) {
|
||||||
encryptHeldBookUsingSign(sign, heldItemType, player, hand);
|
encryptHeldBookUsingSign(sign, heldItemType, player, hand);
|
||||||
} else if (signLineEquals(sign, 1, "[Decrypt]", ChatColor.DARK_BLUE)) {
|
} else if (signLineEquals(sign, 1, "[Decrypt]", ChatColor.DARK_BLUE)) {
|
||||||
@ -109,10 +114,11 @@ public class SignEventListener implements Listener {
|
|||||||
getSignLine2Color(sign) == ChatColor.DARK_GREEN) {
|
getSignLine2Color(sign) == ChatColor.DARK_GREEN) {
|
||||||
giveBook(sign, player);
|
giveBook(sign, player);
|
||||||
} else {
|
} else {
|
||||||
player.sendMessage("Sign command " + sign.getLine(1) + " " + sign.getLine(2) + " invalid");
|
SignSide front = sign.getSide(Side.FRONT);
|
||||||
|
player.sendMessage(String.format("Sign command %s %s is invalid", front.getLine(1),
|
||||||
|
front.getLine(2)));
|
||||||
player.sendMessage(String.valueOf(getSignLine2Color(sign)));
|
player.sendMessage(String.valueOf(getSignLine2Color(sign)));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else if (heldItemType == Material.WRITTEN_BOOK && (event.getAction() == Action.LEFT_CLICK_AIR
|
} else if (heldItemType == Material.WRITTEN_BOOK && (event.getAction() == Action.LEFT_CLICK_AIR
|
||||||
|| event.getAction() == Action.LEFT_CLICK_BLOCK)) {
|
|| event.getAction() == Action.LEFT_CLICK_BLOCK)) {
|
||||||
BookMeta oldBook = (BookMeta) heldItem.getItemMeta();
|
BookMeta oldBook = (BookMeta) heldItem.getItemMeta();
|
||||||
@ -138,7 +144,7 @@ public class SignEventListener implements Listener {
|
|||||||
player.closeInventory();
|
player.closeInventory();
|
||||||
|
|
||||||
//Converts user supplied key into integer form
|
//Converts user supplied key into integer form
|
||||||
String lineText = ChatColor.stripColor(sign.getLine(2));
|
String lineText = ChatColor.stripColor(sign.getSide(Side.FRONT).getLine(2));
|
||||||
String key = EncryptionHelper.getNumberKeyFromStringKey(lineText);
|
String key = EncryptionHelper.getNumberKeyFromStringKey(lineText);
|
||||||
|
|
||||||
ItemStack book = EncryptionHelper.loadEncryptedBook(player, key, false);
|
ItemStack book = EncryptionHelper.loadEncryptedBook(player, key, false);
|
||||||
@ -156,9 +162,9 @@ public class SignEventListener implements Listener {
|
|||||||
* @return <p>The color of the sign</p>
|
* @return <p>The color of the sign</p>
|
||||||
*/
|
*/
|
||||||
private ChatColor getSignLine2Color(Sign sign) {
|
private ChatColor getSignLine2Color(Sign sign) {
|
||||||
String line = sign.getLine(2);
|
String line = sign.getSide(Side.FRONT).getLine(2);
|
||||||
if (!ChatColor.stripColor(line).equals(line)) {
|
if (!ChatColor.stripColor(line).equals(line)) {
|
||||||
return ChatColor.getByChar(sign.getLine(2).substring(1, 2).charAt(0));
|
return ChatColor.getByChar(sign.getSide(Side.FRONT).getLine(2).substring(1, 2).charAt(0));
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -174,7 +180,7 @@ public class SignEventListener implements Listener {
|
|||||||
* @return <p>True if the given string is what's on the sign</p>
|
* @return <p>True if the given string is what's on the sign</p>
|
||||||
*/
|
*/
|
||||||
private boolean signLineEquals(Sign sign, int lineNumber, String compareTo, ChatColor color) {
|
private boolean signLineEquals(Sign sign, int lineNumber, String compareTo, ChatColor color) {
|
||||||
String line = sign.getLine(lineNumber);
|
String line = sign.getSide(Side.FRONT).getLine(lineNumber);
|
||||||
return line.equalsIgnoreCase(color + compareTo);
|
return line.equalsIgnoreCase(color + compareTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,7 +201,7 @@ public class SignEventListener implements Listener {
|
|||||||
|
|
||||||
//Tests if a full file name has been supplied and points to an actual file
|
//Tests if a full file name has been supplied and points to an actual file
|
||||||
String signFile = getBookFolder() + lines[2] + lines[3];
|
String signFile = getBookFolder() + lines[2] + lines[3];
|
||||||
if (FileHelper.bookFileExists(signFile)) {
|
if (BookFileHelper.bookFileExists(signFile)) {
|
||||||
markGiveSignValidity(event, true);
|
markGiveSignValidity(event, true);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
@ -281,7 +287,7 @@ public class SignEventListener implements Listener {
|
|||||||
*/
|
*/
|
||||||
private void encryptHeldBookUsingSign(Sign sign, Material heldItemType, Player player, EquipmentSlot hand) {
|
private void encryptHeldBookUsingSign(Sign sign, Material heldItemType, Player player, EquipmentSlot hand) {
|
||||||
ItemStack eBook;
|
ItemStack eBook;
|
||||||
String[] lines = sign.getLines();
|
String[] lines = sign.getSide(Side.FRONT).getLines();
|
||||||
boolean mainHand = hand == EquipmentSlot.HAND;
|
boolean mainHand = hand == EquipmentSlot.HAND;
|
||||||
if (heldItemType == Material.WRITTEN_BOOK) {
|
if (heldItemType == Material.WRITTEN_BOOK) {
|
||||||
player.closeInventory();
|
player.closeInventory();
|
||||||
@ -300,7 +306,7 @@ public class SignEventListener implements Listener {
|
|||||||
* @param player <p>The player which clicked the sign</p>
|
* @param player <p>The player which clicked the sign</p>
|
||||||
*/
|
*/
|
||||||
private void giveBook(Sign sign, Player player) {
|
private void giveBook(Sign sign, Player player) {
|
||||||
String fileName = ChatColor.stripColor(sign.getLine(2));
|
String fileName = ChatColor.stripColor(sign.getSide(Side.FRONT).getLine(2));
|
||||||
boolean isLoadListNumber = false;
|
boolean isLoadListNumber = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -310,7 +316,7 @@ public class SignEventListener implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Add the third line to the second line for the full filename
|
//Add the third line to the second line for the full filename
|
||||||
String thirdLine = sign.getLine(3);
|
String thirdLine = sign.getSide(Side.FRONT).getLine(3);
|
||||||
if (!isLoadListNumber && thirdLine.length() >= 2) {
|
if (!isLoadListNumber && thirdLine.length() >= 2) {
|
||||||
fileName += ChatColor.stripColor(thirdLine);
|
fileName += ChatColor.stripColor(thirdLine);
|
||||||
}
|
}
|
||||||
|
@ -26,22 +26,22 @@ public enum BookHoldingState {
|
|||||||
UNSIGNED_MAIN_HAND,
|
UNSIGNED_MAIN_HAND,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The player is holding one signed book in their off hand
|
* The player is holding one signed book in their off-hand
|
||||||
*/
|
*/
|
||||||
SIGNED_OFF_HAND,
|
SIGNED_OFF_HAND,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The player is holding one unsigned book in their off hand
|
* The player is holding one unsigned book in their off-hand
|
||||||
*/
|
*/
|
||||||
UNSIGNED_OFF_HAND,
|
UNSIGNED_OFF_HAND,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The player is holding one signed book in their main hand and one unsigned book in their off hand
|
* The player is holding one signed book in their main hand and one unsigned book in their off-hand
|
||||||
*/
|
*/
|
||||||
SIGNED_MAIN_HAND_UNSIGNED_OFF_HAND,
|
SIGNED_MAIN_HAND_UNSIGNED_OFF_HAND,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The player is holding one unsigned book in their main hand and one signed book in their off hand
|
* The player is holding one unsigned book in their main hand and one signed book in their off-hand
|
||||||
*/
|
*/
|
||||||
UNSIGNED_MAIN_HAND_SIGNED_OFF_HAND,
|
UNSIGNED_MAIN_HAND_SIGNED_OFF_HAND,
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ public enum ItemSlot {
|
|||||||
MAIN_HAND,
|
MAIN_HAND,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The item is in the player's off hand
|
* The item is in the player's off-hand
|
||||||
*/
|
*/
|
||||||
OFF_HAND,
|
OFF_HAND,
|
||||||
|
|
||||||
|
@ -6,11 +6,7 @@ import net.knarcraft.bookswithoutborders.state.BookDirectory;
|
|||||||
import net.md_5.bungee.api.ChatColor;
|
import net.md_5.bungee.api.ChatColor;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@ -21,9 +17,9 @@ import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig
|
|||||||
/**
|
/**
|
||||||
* Helper class for dealing with files
|
* Helper class for dealing with files
|
||||||
*/
|
*/
|
||||||
public final class FileHelper {
|
public final class BookFileHelper {
|
||||||
|
|
||||||
private FileHelper() {
|
private BookFileHelper() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -102,7 +98,7 @@ public final class FileHelper {
|
|||||||
if (file == null) {
|
if (file == null) {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
return FileHelper.listFiles(sender, file);
|
return BookFileHelper.listFiles(sender, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -113,7 +109,7 @@ public final class FileHelper {
|
|||||||
*/
|
*/
|
||||||
public static void printBooks(CommandSender sender, boolean listPublic) {
|
public static void printBooks(CommandSender sender, boolean listPublic) {
|
||||||
List<String> availableBooks = BooksWithoutBorders.getAvailableBooks(sender, listPublic);
|
List<String> availableBooks = BooksWithoutBorders.getAvailableBooks(sender, listPublic);
|
||||||
FileHelper.printFiles(sender, availableBooks);
|
BookFileHelper.printFiles(sender, availableBooks);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -162,9 +158,8 @@ public final class FileHelper {
|
|||||||
String userName = data[1].substring(0, data[1].length() - 4);
|
String userName = data[1].substring(0, data[1].length() - 4);
|
||||||
data[1] = BookHelper.authorFromUUID(userName) + extension;
|
data[1] = BookHelper.authorFromUUID(userName) + extension;
|
||||||
fileList.add(String.join(separator, data));
|
fileList.add(String.join(separator, data));
|
||||||
} else {
|
|
||||||
fileList.add(fileName);
|
|
||||||
}
|
}
|
||||||
|
fileList.add(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
return fileList;
|
return fileList;
|
||||||
@ -187,15 +182,4 @@ public final class FileHelper {
|
|||||||
return foundDuplicates;
|
return foundDuplicates;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a buffered reader given an input stream
|
|
||||||
*
|
|
||||||
* @param inputStream <p>The input stream to read</p>
|
|
||||||
* @return <p>A buffered reader reading the input stream</p>
|
|
||||||
*/
|
|
||||||
public static BufferedReader getBufferedReaderFromInputStream(InputStream inputStream) {
|
|
||||||
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
|
|
||||||
return new BufferedReader(inputStreamReader);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,13 +1,12 @@
|
|||||||
package net.knarcraft.bookswithoutborders.utility;
|
package net.knarcraft.bookswithoutborders.utility;
|
||||||
|
|
||||||
import net.md_5.bungee.api.ChatColor;
|
import net.knarcraft.knarlib.property.ColorConversion;
|
||||||
|
import net.knarcraft.knarlib.util.ColorHelper;
|
||||||
import org.bukkit.inventory.meta.BookMeta;
|
import org.bukkit.inventory.meta.BookMeta;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class for formatting text to fit books
|
* A class for formatting text to fit books
|
||||||
@ -109,26 +108,10 @@ public final class BookFormatter {
|
|||||||
public static BookMeta formatPages(BookMeta bookMeta) {
|
public static BookMeta formatPages(BookMeta bookMeta) {
|
||||||
List<String> formattedPages = new ArrayList<>(Objects.requireNonNull(bookMeta).getPageCount());
|
List<String> formattedPages = new ArrayList<>(Objects.requireNonNull(bookMeta).getPageCount());
|
||||||
for (String page : bookMeta.getPages()) {
|
for (String page : bookMeta.getPages()) {
|
||||||
formattedPages.add(BookFormatter.translateAllColorCodes(page));
|
formattedPages.add(ColorHelper.translateColorCodes(page, ColorConversion.RGB));
|
||||||
}
|
}
|
||||||
bookMeta.setPages(formattedPages);
|
bookMeta.setPages(formattedPages);
|
||||||
return bookMeta;
|
return bookMeta;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Translates all found color codes to formatting in a string
|
|
||||||
*
|
|
||||||
* @param message <p>The string to search for color codes</p>
|
|
||||||
* @return <p>The message with color codes translated</p>
|
|
||||||
*/
|
|
||||||
public static String translateAllColorCodes(String message) {
|
|
||||||
message = ChatColor.translateAlternateColorCodes('&', message);
|
|
||||||
Pattern pattern = Pattern.compile("(#[a-fA-F0-9]{6})");
|
|
||||||
Matcher matcher = pattern.matcher(message);
|
|
||||||
while (matcher.find()) {
|
|
||||||
message = message.replace(matcher.group(), "" + ChatColor.of(matcher.group()));
|
|
||||||
}
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package net.knarcraft.bookswithoutborders.utility;
|
|||||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
||||||
import net.knarcraft.bookswithoutborders.state.BookDirectory;
|
import net.knarcraft.bookswithoutborders.state.BookDirectory;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -60,8 +61,23 @@ public final class BookLoader {
|
|||||||
//Get the full path of the book to load
|
//Get the full path of the book to load
|
||||||
File file = getFullPath(sender, fileName, bookDirectory, directory);
|
File file = getFullPath(sender, fileName, bookDirectory, directory);
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
|
//Try converting the username to UUID
|
||||||
|
String titleAuthorSeparator = BooksWithoutBordersConfig.getTitleAuthorSeparator();
|
||||||
|
String[] data = fileName.split(titleAuthorSeparator);
|
||||||
|
String extension = data[1].substring(data[1].length() - 4);
|
||||||
|
String userName = data[1].substring(0, data[1].length() - 4);
|
||||||
|
Player player = Bukkit.getPlayer(userName);
|
||||||
|
if (player != null) {
|
||||||
|
data[1] = player.getUniqueId() + extension;
|
||||||
|
file = getFullPath(sender, String.join(titleAuthorSeparator, data), bookDirectory, directory);
|
||||||
|
if (file == null) {
|
||||||
|
BooksWithoutBorders.sendErrorMessage(sender, "Incorrect file name!");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Make sure the player can pay for the book
|
//Make sure the player can pay for the book
|
||||||
if (BooksWithoutBordersConfig.booksHavePrice() &&
|
if (BooksWithoutBordersConfig.booksHavePrice() &&
|
||||||
@ -120,13 +136,11 @@ public final class BookLoader {
|
|||||||
String slash = BooksWithoutBordersConfig.getSlash();
|
String slash = BooksWithoutBordersConfig.getSlash();
|
||||||
String bookFolder = BooksWithoutBordersConfig.getBookFolder();
|
String bookFolder = BooksWithoutBordersConfig.getBookFolder();
|
||||||
if (bookDirectory == BookDirectory.ENCRYPTED) {
|
if (bookDirectory == BookDirectory.ENCRYPTED) {
|
||||||
file = FileHelper.getBookFile(bookFolder + "Encrypted" + slash + directory + slash + fileName);
|
file = BookFileHelper.getBookFile(bookFolder + "Encrypted" + slash + directory + slash + fileName);
|
||||||
} else {
|
} else {
|
||||||
file = FileHelper.getBookFile(BookHelper.getBookDirectoryPathString(bookDirectory, sender) + fileName);
|
file = BookFileHelper.getBookFile(BookHelper.getBookDirectoryPathString(bookDirectory, sender) + fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file == null || !file.isFile()) {
|
if (file == null || !file.isFile()) {
|
||||||
BooksWithoutBorders.sendErrorMessage(sender, "Incorrect file name!");
|
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
return file;
|
return file;
|
||||||
|
@ -1,18 +1,22 @@
|
|||||||
package net.knarcraft.bookswithoutborders.utility;
|
package net.knarcraft.bookswithoutborders.utility;
|
||||||
|
|
||||||
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
||||||
|
import net.knarcraft.knarlib.util.FileHelper;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
import org.bukkit.inventory.meta.BookMeta;
|
import org.bukkit.inventory.meta.BookMeta;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileReader;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import static net.knarcraft.bookswithoutborders.utility.BookHelper.authorFromUUID;
|
import static net.knarcraft.bookswithoutborders.utility.BookHelper.authorFromUUID;
|
||||||
import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.fixName;
|
import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.fixName;
|
||||||
@ -83,7 +87,7 @@ public final class BookToFromTextHelper {
|
|||||||
* @throws IOException <p>If unable to save the book</p>
|
* @throws IOException <p>If unable to save the book</p>
|
||||||
*/
|
*/
|
||||||
public static void bookToTXT(String folderPath, String fileName, BookMeta bookMetadata) throws IOException {
|
public static void bookToTXT(String folderPath, String fileName, BookMeta bookMetadata) throws IOException {
|
||||||
FileWriter fileWriter = new FileWriter(folderPath + fileName + ".txt");
|
FileWriter fileWriter = new FileWriter(folderPath + fileName + ".txt", StandardCharsets.UTF_8);
|
||||||
PrintWriter printWriter = new PrintWriter(fileWriter);
|
PrintWriter printWriter = new PrintWriter(fileWriter);
|
||||||
List<String> pages = bookMetadata.getPages();
|
List<String> pages = bookMetadata.getPages();
|
||||||
|
|
||||||
@ -155,13 +159,13 @@ public final class BookToFromTextHelper {
|
|||||||
List<String> rawPages;
|
List<String> rawPages;
|
||||||
try {
|
try {
|
||||||
rawPages = readTextFile(file);
|
rawPages = readTextFile(file);
|
||||||
} catch (IOException e) {
|
} catch (IOException exception) {
|
||||||
e.printStackTrace();
|
BooksWithoutBorders.getInstance().getLogger().log(Level.SEVERE, "Unable to read text file");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Parse the generation from the book data
|
//Parse the generation from the book data
|
||||||
if (rawPages != null && rawPages.size() > 0 && rawPages.get(0).startsWith("Generation:")) {
|
if (rawPages != null && !rawPages.isEmpty() && rawPages.get(0).startsWith("Generation:")) {
|
||||||
bookMetadata.setGeneration(BookMeta.Generation.valueOf(rawPages.get(0).split(":")[1]));
|
bookMetadata.setGeneration(BookMeta.Generation.valueOf(rawPages.get(0).split(":")[1]));
|
||||||
rawPages.remove(0);
|
rawPages.remove(0);
|
||||||
}
|
}
|
||||||
@ -186,7 +190,7 @@ public final class BookToFromTextHelper {
|
|||||||
*/
|
*/
|
||||||
private static List<String> readTextFile(File file) throws IOException {
|
private static List<String> readTextFile(File file) throws IOException {
|
||||||
List<String> rawPages = new ArrayList<>();
|
List<String> rawPages = new ArrayList<>();
|
||||||
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
|
BufferedReader bufferedReader = FileHelper.getBufferedReaderFromInputStream(new FileInputStream(file));
|
||||||
|
|
||||||
//Use the first line to decide if we are loading a book, or creating a new book
|
//Use the first line to decide if we are loading a book, or creating a new book
|
||||||
String firstLine = bufferedReader.readLine();
|
String firstLine = bufferedReader.readLine();
|
||||||
|
@ -16,6 +16,7 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getBookFolder;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getBookFolder;
|
||||||
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getSlash;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getSlash;
|
||||||
@ -255,8 +256,8 @@ public final class EncryptionHelper {
|
|||||||
BooksWithoutBorders.sendErrorMessage(BooksWithoutBorders.getConsoleSender(), "Unable to create encryption group folder!");
|
BooksWithoutBorders.sendErrorMessage(BooksWithoutBorders.getConsoleSender(), "Unable to create encryption group folder!");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception exception) {
|
||||||
e.printStackTrace();
|
BooksWithoutBorders.getInstance().getLogger().log(Level.SEVERE, "Unable to save group encrypted book");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -279,8 +280,7 @@ public final class EncryptionHelper {
|
|||||||
if (!file.isFile()) {
|
if (!file.isFile()) {
|
||||||
try {
|
try {
|
||||||
BookToFromTextHelper.bookToYml(path, fileName, bookMetadata);
|
BookToFromTextHelper.bookToYml(path, fileName, bookMetadata);
|
||||||
} catch (IOException e) {
|
} catch (IOException exception) {
|
||||||
e.printStackTrace();
|
|
||||||
BooksWithoutBorders.sendErrorMessage(player, "Group encrypted failed!");
|
BooksWithoutBorders.sendErrorMessage(player, "Group encrypted failed!");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -312,8 +312,7 @@ public final class EncryptionHelper {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
BookToFromTextHelper.bookToYml(path, fileName, bookMetaData);
|
BookToFromTextHelper.bookToYml(path, fileName, bookMetaData);
|
||||||
} catch (IOException e) {
|
} catch (IOException exception) {
|
||||||
e.printStackTrace();
|
|
||||||
BooksWithoutBorders.sendErrorMessage(player, "Encryption failed!");
|
BooksWithoutBorders.sendErrorMessage(player, "Encryption failed!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,90 @@
|
|||||||
|
package net.knarcraft.bookswithoutborders.utility;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A converter from an integer to a roman numeral
|
||||||
|
*/
|
||||||
|
public final class IntegerToRomanConverter {
|
||||||
|
|
||||||
|
private final static List<Integer> romanValues = new ArrayList<>();
|
||||||
|
private final static List<Character> romanCharacters = new ArrayList<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
// Initialize the roman numbers
|
||||||
|
romanValues.add(1000);
|
||||||
|
romanValues.add(500);
|
||||||
|
romanValues.add(100);
|
||||||
|
romanValues.add(50);
|
||||||
|
romanValues.add(10);
|
||||||
|
romanValues.add(5);
|
||||||
|
romanValues.add(1);
|
||||||
|
|
||||||
|
romanCharacters.add('M');
|
||||||
|
romanCharacters.add('D');
|
||||||
|
romanCharacters.add('C');
|
||||||
|
romanCharacters.add('L');
|
||||||
|
romanCharacters.add('X');
|
||||||
|
romanCharacters.add('V');
|
||||||
|
romanCharacters.add('I');
|
||||||
|
}
|
||||||
|
|
||||||
|
private IntegerToRomanConverter() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the given number as a roman number string
|
||||||
|
*
|
||||||
|
* @param number <p>The number to convert</p>
|
||||||
|
* @return <p>The roman representation of the number</p>
|
||||||
|
*/
|
||||||
|
public static String getRomanNumber(int number) {
|
||||||
|
StringBuilder output = new StringBuilder();
|
||||||
|
int remainder = number;
|
||||||
|
for (int i = 0; i < romanCharacters.size(); i++) {
|
||||||
|
int romanValue = romanValues.get(i);
|
||||||
|
char romanCharacter = romanCharacters.get(i);
|
||||||
|
|
||||||
|
// Repeat the roman character, and calculate the new remainder
|
||||||
|
if (remainder >= romanValue) {
|
||||||
|
output.append(repeat(romanCharacter, remainder / romanValue));
|
||||||
|
remainder = remainder % romanValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit early to prevent unexpected trailing characters
|
||||||
|
if (remainder == 0) {
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate the special case IV and similar
|
||||||
|
for (int j = i; j < romanCharacters.size(); j++) {
|
||||||
|
int value = romanValues.get(j);
|
||||||
|
int difference = Math.max(romanValue - value, 0);
|
||||||
|
|
||||||
|
/* If the remainder is "one" less than the current roman value, we hit the IV/IX/XL case.
|
||||||
|
Note that 5 triggers the special case when 10 is tested, as 5 = 10 - 5, which requires a test, so it
|
||||||
|
can be filtered out. */
|
||||||
|
if (remainder == difference && value != romanValue / 2) {
|
||||||
|
output.append(romanCharacters.get(j)).append(romanCharacter);
|
||||||
|
remainder = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Repeats the given character
|
||||||
|
*
|
||||||
|
* @param character <p>The character to repeat</p>
|
||||||
|
* @param times <p>The number of times to repeat the character</p>
|
||||||
|
* @return <p>The repeated string</p>
|
||||||
|
*/
|
||||||
|
private static String repeat(char character, int times) {
|
||||||
|
return String.valueOf(character).repeat(Math.max(0, times));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -6,43 +6,9 @@ import java.util.List;
|
|||||||
/**
|
/**
|
||||||
* Helper class for getting string lists required for auto-completion
|
* Helper class for getting string lists required for auto-completion
|
||||||
*/
|
*/
|
||||||
public final class TabCompletionHelper {
|
public final class TabCompletionTypeHelper {
|
||||||
|
|
||||||
private TabCompletionHelper() {
|
private TabCompletionTypeHelper() {
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds tab complete values that contain the typed text
|
|
||||||
*
|
|
||||||
* @param values <p>The values to filter</p>
|
|
||||||
* @param typedText <p>The text the player has started typing</p>
|
|
||||||
* @return <p>The given string values that contain the player's typed text</p>
|
|
||||||
*/
|
|
||||||
public static List<String> filterMatchingContains(List<String> values, String typedText) {
|
|
||||||
List<String> configValues = new ArrayList<>();
|
|
||||||
for (String value : values) {
|
|
||||||
if (value.toLowerCase().contains(typedText.toLowerCase())) {
|
|
||||||
configValues.add(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return configValues;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds tab complete values that match the start of the typed text
|
|
||||||
*
|
|
||||||
* @param values <p>The values to filter</p>
|
|
||||||
* @param typedText <p>The text the player has started typing</p>
|
|
||||||
* @return <p>The given string values that start with the player's typed text</p>
|
|
||||||
*/
|
|
||||||
public static List<String> filterMatchingStartsWith(List<String> values, String typedText) {
|
|
||||||
List<String> configValues = new ArrayList<>();
|
|
||||||
for (String value : values) {
|
|
||||||
if (value.toLowerCase().startsWith(typedText.toLowerCase())) {
|
|
||||||
configValues.add(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return configValues;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
@ -1,92 +0,0 @@
|
|||||||
package net.knarcraft.bookswithoutborders.utility;
|
|
||||||
|
|
||||||
import org.bukkit.plugin.Plugin;
|
|
||||||
import org.bukkit.scheduler.BukkitScheduler;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The update checker is responsible for looking for new updates
|
|
||||||
*/
|
|
||||||
public final class UpdateChecker {
|
|
||||||
|
|
||||||
private final static String updateNotice = "A new update is available: %s (You are still on %s)";
|
|
||||||
|
|
||||||
private UpdateChecker() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if there's a new update available, and alerts the user if necessary
|
|
||||||
*/
|
|
||||||
public static void checkForUpdate(Plugin plugin, String apiResourceURL, Supplier<String> getVersionMethod,
|
|
||||||
Consumer<String> setVersionMethod) {
|
|
||||||
BukkitScheduler scheduler = plugin.getServer().getScheduler();
|
|
||||||
scheduler.runTaskAsynchronously(plugin, () -> UpdateChecker.queryAPI(plugin, apiResourceURL, getVersionMethod,
|
|
||||||
setVersionMethod));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Queries the spigot API to check for a newer version, and informs the user
|
|
||||||
*/
|
|
||||||
private static void queryAPI(Plugin plugin, String APIResourceURL, Supplier<String> getVersionMethod,
|
|
||||||
Consumer<String> setVersionMethod) {
|
|
||||||
try {
|
|
||||||
InputStream inputStream = new URL(APIResourceURL).openStream();
|
|
||||||
BufferedReader reader = FileHelper.getBufferedReaderFromInputStream(inputStream);
|
|
||||||
//There should only be one line of output
|
|
||||||
String newVersion = reader.readLine();
|
|
||||||
reader.close();
|
|
||||||
|
|
||||||
String oldVersion = getVersionMethod.get();
|
|
||||||
//If there is a newer version, notify the user
|
|
||||||
if (isVersionHigher(oldVersion, newVersion)) {
|
|
||||||
plugin.getLogger().log(Level.INFO, getUpdateAvailableString(newVersion, oldVersion));
|
|
||||||
if (setVersionMethod != null) {
|
|
||||||
setVersionMethod.accept(newVersion);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
plugin.getLogger().log(Level.WARNING, "Unable to get newest version.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the string to display to a user to alert about a new update
|
|
||||||
*
|
|
||||||
* @param newVersion <p>The new available plugin version</p>
|
|
||||||
* @param oldVersion <p>The old (current) plugin version</p>
|
|
||||||
* @return <p>The string to display</p>
|
|
||||||
*/
|
|
||||||
public static String getUpdateAvailableString(String newVersion, String oldVersion) {
|
|
||||||
return String.format(updateNotice, newVersion, oldVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decides whether one version number is higher than another
|
|
||||||
*
|
|
||||||
* @param oldVersion <p>The old version to check</p>
|
|
||||||
* @param newVersion <p>The new version to check</p>
|
|
||||||
* @return <p>True if the new version is higher than the old one</p>
|
|
||||||
*/
|
|
||||||
public static boolean isVersionHigher(String oldVersion, String newVersion) {
|
|
||||||
String[] oldVersionParts = oldVersion.split("\\.");
|
|
||||||
String[] newVersionParts = newVersion.split("\\.");
|
|
||||||
int versionLength = Math.max(oldVersionParts.length, newVersionParts.length);
|
|
||||||
for (int i = 0; i < versionLength; i++) {
|
|
||||||
int oldVersionNumber = oldVersionParts.length > i ? Integer.parseInt(oldVersionParts[i]) : 0;
|
|
||||||
int newVersionNumber = newVersionParts.length > i ? Integer.parseInt(newVersionParts[i]) : 0;
|
|
||||||
if (newVersionNumber != oldVersionNumber) {
|
|
||||||
return newVersionNumber > oldVersionNumber;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -30,4 +30,5 @@ Options:
|
|||||||
# Whether to display "COPY" or "COPY_OF_COPY" instead of "ORIGINAL" when a book is copied. This also uses the
|
# Whether to display "COPY" or "COPY_OF_COPY" instead of "ORIGINAL" when a book is copied. This also uses the
|
||||||
# vanilla behavior where a copy of a copy cannot be copied further.
|
# vanilla behavior where a copy of a copy cannot be copied further.
|
||||||
Change_Generation_On_Copy: false
|
Change_Generation_On_Copy: false
|
||||||
|
# Whether to enable hitting a chiseled bookshelf while sneaking to see the shelf's contents.
|
||||||
|
Enable_Book_Peeking: false
|
@ -1,10 +1,10 @@
|
|||||||
name: BooksWithoutBorders
|
name: BooksWithoutBorders
|
||||||
version: '${project.version}'
|
version: '${project.version}'
|
||||||
main: net.knarcraft.bookswithoutborders.BooksWithoutBorders
|
main: net.knarcraft.bookswithoutborders.BooksWithoutBorders
|
||||||
api-version: 1.18
|
api-version: '1.20'
|
||||||
prefix: Books Without Borders
|
prefix: 'Books Without Borders'
|
||||||
authors: [ EpicKnarvik97, AkiraAkiba ]
|
authors: [ EpicKnarvik97, AkiraAkiba ]
|
||||||
description: A continuation of the original Books Without Borders
|
description: 'A continuation of the original Books Without Borders'
|
||||||
softdepend: [ Vault ]
|
softdepend: [ Vault ]
|
||||||
website: https://www.spigotmc.org/resources/books-without-borders-updated.96069/
|
website: https://www.spigotmc.org/resources/books-without-borders-updated.96069/
|
||||||
dev-url: https://git.knarcraft.net/EpicKnarvik97/Books-Without-Borders
|
dev-url: https://git.knarcraft.net/EpicKnarvik97/Books-Without-Borders
|
||||||
@ -126,11 +126,12 @@ permissions:
|
|||||||
bookswithoutborders.reload: true
|
bookswithoutborders.reload: true
|
||||||
bookswithoutborders.setgeneration: true
|
bookswithoutborders.setgeneration: true
|
||||||
bookswithoutborders.use:
|
bookswithoutborders.use:
|
||||||
description: Allows player to use commands to save/load/delete in their personal directory
|
description: Allows player to use commands to save/load/delete in their personal directory, and peeking at bookshelves if enabled
|
||||||
children:
|
children:
|
||||||
bookswithoutborders.save: true
|
bookswithoutborders.save: true
|
||||||
bookswithoutborders.load: true
|
bookswithoutborders.load: true
|
||||||
bookswithoutborders.delete: true
|
bookswithoutborders.delete: true
|
||||||
|
bookswithoutborders.peekbookshelf: true
|
||||||
bookswithoutborders.alterbooks:
|
bookswithoutborders.alterbooks:
|
||||||
description: Allows player to change books' data such as lore/title/author/generation/formatting and unsigning books
|
description: Allows player to change books' data such as lore/title/author/generation/formatting and unsigning books
|
||||||
children:
|
children:
|
||||||
@ -191,3 +192,5 @@ permissions:
|
|||||||
description: Allows player to reload this plugin
|
description: Allows player to reload this plugin
|
||||||
bookswithoutborders.setgeneration:
|
bookswithoutborders.setgeneration:
|
||||||
description: Allows player to change the generation of a book (Original, Copy, Copy of Copy)
|
description: Allows player to change the generation of a book (Original, Copy, Copy of Copy)
|
||||||
|
bookswithoutborders.peekbookshelf:
|
||||||
|
description: Allows player to left-click a bookshelf to see the contents of the shelf
|
@ -1,9 +1,9 @@
|
|||||||
package net.knarcraft.bookswithoutborders.encryption;
|
package net.knarcraft.bookswithoutborders.encryption;
|
||||||
|
|
||||||
import junit.framework.Assert;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static junit.framework.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotSame;
|
||||||
|
|
||||||
public class AESTest {
|
public class AESTest {
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ public class AESTest {
|
|||||||
AES aes = new AES(AES.generateIV(), AES.generateIV());
|
AES aes = new AES(AES.generateIV(), AES.generateIV());
|
||||||
|
|
||||||
String encrypted = aes.encryptDecryptText(plainText, password, true);
|
String encrypted = aes.encryptDecryptText(plainText, password, true);
|
||||||
Assert.assertNotSame(encrypted, plainText);
|
assertNotSame(encrypted, plainText);
|
||||||
String decrypted = aes.encryptDecryptText(encrypted, password, false);
|
String decrypted = aes.encryptDecryptText(encrypted, password, false);
|
||||||
assertEquals(plainText, decrypted);
|
assertEquals(plainText, decrypted);
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
package net.knarcraft.bookswithoutborders.util;
|
package net.knarcraft.bookswithoutborders.util;
|
||||||
|
|
||||||
import net.knarcraft.bookswithoutborders.utility.FileHelper;
|
import net.knarcraft.bookswithoutborders.utility.BookFileHelper;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
public class FileHelperTest {
|
public class BookFileHelperTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findDuplicatesTest() {
|
public void findDuplicatesTest() {
|
||||||
@ -17,9 +17,9 @@ public class FileHelperTest {
|
|||||||
files[2] = new File("test/asd/(3)book+)Crab.yml");
|
files[2] = new File("test/asd/(3)book+)Crab.yml");
|
||||||
files[3] = new File("test/asd/(2)book+)Crab.yml");
|
files[3] = new File("test/asd/(2)book+)Crab.yml");
|
||||||
files[4] = new File("test/asd/(1)book+)Crab.yml");
|
files[4] = new File("test/asd/(1)book+)Crab.yml");
|
||||||
assertEquals(4, FileHelper.findDuplicates(files, "book+)Crab.yml"));
|
assertEquals(4, BookFileHelper.findDuplicates(files, "book+)Crab.yml"));
|
||||||
assertEquals(1, FileHelper.findDuplicates(files, "book+)Fish.yml"));
|
assertEquals(1, BookFileHelper.findDuplicates(files, "book+)Fish.yml"));
|
||||||
assertEquals(0, FileHelper.findDuplicates(files, "book+)Horse.yml"));
|
assertEquals(0, BookFileHelper.findDuplicates(files, "book+)Horse.yml"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package net.knarcraft.bookswithoutborders.util;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static net.knarcraft.bookswithoutborders.utility.IntegerToRomanConverter.getRomanNumber;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A test class for IntegerToRomanConverter
|
||||||
|
*/
|
||||||
|
public class IntegerToRomanConverterTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void basicNumbersTest() {
|
||||||
|
assertEquals("I", getRomanNumber(1));
|
||||||
|
assertEquals("II", getRomanNumber(2));
|
||||||
|
assertEquals("III", getRomanNumber(3));
|
||||||
|
assertEquals("IV", getRomanNumber(4));
|
||||||
|
assertEquals("V", getRomanNumber(5));
|
||||||
|
assertEquals("X", getRomanNumber(10));
|
||||||
|
assertEquals("XV", getRomanNumber(15));
|
||||||
|
assertEquals("XX", getRomanNumber(20));
|
||||||
|
assertEquals("L", getRomanNumber(50));
|
||||||
|
assertEquals("C", getRomanNumber(100));
|
||||||
|
assertEquals("D", getRomanNumber(500));
|
||||||
|
assertEquals("M", getRomanNumber(1000));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void nineFourTest() {
|
||||||
|
assertEquals("IV", getRomanNumber(4));
|
||||||
|
assertEquals("IX", getRomanNumber(9));
|
||||||
|
assertEquals("XIV", getRomanNumber(14));
|
||||||
|
assertEquals("XIX", getRomanNumber(19));
|
||||||
|
assertEquals("XXIV", getRomanNumber(24));
|
||||||
|
assertEquals("XL", getRomanNumber(40));
|
||||||
|
assertEquals("IL", getRomanNumber(49));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user