First commit. Rewrite started

This commit is contained in:
Kristian Knarvik 2021-08-26 20:18:37 +02:00
commit 78828ac9fa
6 changed files with 2645 additions and 0 deletions

81
pom.xml Normal file
View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.knarcraft.bookswithoutborders</groupId>
<artifactId>books-without-borders</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Books Without Borders</name>
<description>A continuation of the original Books Without Borders</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<repositories>
<repository>
<id>spigotmc-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.17.1-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.MilkBowl</groupId>
<artifactId>VaultAPI</artifactId>
<version>1.7</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,432 @@
package net.knarcraft.bookswithoutborders;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.block.Sign;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.BookMeta;
import org.bukkit.inventory.meta.ItemMeta;
/**
* A listener for relevant events
*/
public class BooksWithoutBordersListener implements Listener {
private final String slash = BooksWithoutBorders.SLASH;
private final String bookFolder = BooksWithoutBorders.bwb.getDataFolder().getAbsolutePath() + slash + "Books" + slash;
/**
* Updates old books to a newer format
*
* @param player <p>The player holding the book</p>
* @param oldBook <p>Metadata about the held book</p>
* @return <p>An updated book</p>
*/
public ItemStack updateBook(Player player, BookMeta oldBook) {
//handles hacked title-less books
if (oldBook.getTitle() == null || oldBook.getTitle().length() < 3) {
return null;
}
if (oldBook.getTitle().substring(oldBook.getTitle().length() - 3).equalsIgnoreCase("[U]")) {
String fileName;
if (oldBook.getAuthor() != null && oldBook.getAuthor().equalsIgnoreCase("unknown")) {
//Unknown author is ignored
fileName = oldBook.getTitle();
} else {
fileName = oldBook.getTitle() + BooksWithoutBorders.titleAuthorSeparator + oldBook.getAuthor();
}
String cleanPlayerName = BooksWithoutBorders.bwb.cleanString(player.getName());
String[] possiblePaths = new String[]{
bookFolder + fileName + ".yml",
bookFolder + fileName + ".txt",
bookFolder + cleanPlayerName + slash + fileName + ".yml",
bookFolder + cleanPlayerName + slash + fileName + ".txt"
};
for (String path : possiblePaths) {
File file = new File(path);
if (file.isFile()) {
return BooksWithoutBorders.bwb.loadBook(player, fileName, "true", "player");
}
}
return null;
}
return null;
}
@EventHandler
public void onHold(PlayerItemHeldEvent e) {
Player player = e.getPlayer();
int selectedSlot = e.getNewSlot();
PlayerInventory playerInventory = player.getInventory();
ItemStack selectedItem = playerInventory.getItem(selectedSlot);
//Ignore irrelevant items
if (selectedItem == null || selectedItem.getType() != Material.WRITTEN_BOOK) {
return;
}
ItemMeta itemMetadata = selectedItem.getItemMeta();
if (itemMetadata == null) {
return;
}
//Update the book the user is viewing
updateBookInHand(player, itemMetadata, true);
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent e) {
//Handle new players
if (!BooksWithoutBorders.bwb.hasPlayedBefore(e.getPlayer().getName())) {
Player player = e.getPlayer();
boolean sendMessage = true;
//Gives new players necessary books
for (String bookName : BooksWithoutBorders.firstBooks) {
sendMessage = giveBookToNewPlayer(bookName, player, sendMessage);
}
}
//Updates any books in either hand
ItemStack mainHandItem = e.getPlayer().getInventory().getItemInMainHand();
ItemStack offHandItem = e.getPlayer().getInventory().getItemInOffHand();
if (mainHandItem.getType() == Material.WRITTEN_BOOK) {
ItemMeta itemMetadata = mainHandItem.getItemMeta();
updateBookInHand(e.getPlayer(), itemMetadata, true);
}
if (offHandItem.getType() == Material.WRITTEN_BOOK) {
ItemMeta itemMetadata = offHandItem.getItemMeta();
updateBookInHand(e.getPlayer(), itemMetadata, false);
}
}
/**
* Gives a book to a player joining for the first time
* @param bookName <p>The name of the book to give</p>
* @param player <p>The player which just joined</p>
* @param sendMessage <p>Whether to send a message to the joining player</p>
* @return <p>True if a message has yet to be sent</p>
*/
private boolean giveBookToNewPlayer(String bookName, Player player, boolean sendMessage) {
if (!bookName.equalsIgnoreCase(" ")) {
//handles loadlist numbers
for (int x = 0; x < bookName.length(); x++) {
if (!Character.isDigit(bookName.charAt(x))) {
break;
}
if (x == bookName.length() - 1) {
BooksWithoutBorders.loadList.put(player.getName(), BooksWithoutBorders.bwb.listFiles(player, true, 0, true));
}
}
ItemStack newBook = BooksWithoutBorders.bwb.loadBook(player, bookName, "true", "public");
if (newBook != null) {
player.getInventory().addItem(newBook);
}
if (!BooksWithoutBorders.fBMessage.equalsIgnoreCase(" ") && newBook != null && sendMessage) {
sendMessage = false;
final Player fp = player;
BooksWithoutBorders.bwb.getServer().getScheduler().scheduleSyncDelayedTask(BooksWithoutBorders.bwb,
() -> fp.sendMessage(BooksWithoutBorders.fBMessage), 40L);
}
}
return sendMessage;
}
/**
* Updates a book in one of the player's hands
*
* @param player <p>The player to update</p>
* @param itemMetadata <p>Information about the held book</p>
* @param mainHand <p>Whether to update the book in the player's main hand</p>
*/
private void updateBookInHand(Player player, ItemMeta itemMetadata, boolean mainHand) {
PlayerInventory playerInventory = player.getInventory();
ItemStack updatedBook = updateBook(player, (BookMeta) itemMetadata);
if (updatedBook != null) {
if (mainHand) {
playerInventory.setItemInMainHand(updatedBook);
} else {
playerInventory.setItemInOffHand(updatedBook);
}
}
}
@EventHandler
public void onSignChange(SignChangeEvent e) {
if (e.getLine(0).equalsIgnoreCase("[BwB]") && e.getPlayer().hasPermission("bookswithoutborders.signs")) {
e.setLine(0, ChatColor.DARK_GREEN + "[BwB]");
if ((e.getLine(1).equalsIgnoreCase("[Encrypt]") || e.getLine(1).equalsIgnoreCase("[Decrypt]") || e.getLine(1).equalsIgnoreCase("[Give]")) && e.getLine(2).replace(" ", "").length() > 0) {
e.setLine(1, ChatColor.DARK_BLUE + e.getLine(1));
if (e.getLine(1).equalsIgnoreCase(ChatColor.DARK_BLUE + "[Encrypt]") || e.getLine(1).equalsIgnoreCase(ChatColor.DARK_BLUE + "[Decrypt]")) {
e.setLine(2, ChatColor.MAGIC + e.getLine(2));
e.setLine(3, ChatColor.DARK_BLUE + e.getLine(3));
}
if (e.getLine(1).equalsIgnoreCase(ChatColor.DARK_BLUE + "[Give]")) {
if (e.getLine(2).length() > 13 || e.getLine(3).length() > 13) {
e.getPlayer().sendMessage(ChatColor.RED + "[Give] signs' 3rd and 4th lines must be 13 characters or less!");
e.setLine(2, ChatColor.DARK_RED + e.getLine(2));
e.setLine(3, ChatColor.DARK_RED + e.getLine(3));
return;
}
//Tests if a full file name has been supplied
if ((new File(BooksWithoutBorders.bwb.getDataFolder().getAbsolutePath() + BooksWithoutBorders.SLASH + "Books" + BooksWithoutBorders.SLASH + e.getLine(2) + e.getLine(3)).isFile()) ||
(new File(BooksWithoutBorders.bwb.getDataFolder().getAbsolutePath() + BooksWithoutBorders.SLASH + "Books" + BooksWithoutBorders.SLASH + e.getLine(2) + e.getLine(3) + ".txt").isFile()) ||
(new File(BooksWithoutBorders.bwb.getDataFolder().getAbsolutePath() + BooksWithoutBorders.SLASH + "Books" + BooksWithoutBorders.SLASH + e.getLine(2) + e.getLine(3) + ".yml").isFile())) {
e.setLine(2, ChatColor.DARK_GREEN + e.getLine(2));
e.setLine(3, ChatColor.DARK_GREEN + e.getLine(3));
}
//Tests if a load list number has been supplied
else {
File dirFile = new File(BooksWithoutBorders.bwb.getDataFolder().getAbsolutePath() + BooksWithoutBorders.SLASH + "Books");
for (int x = 0; x < e.getLine(2).length(); x++) {
if (!Character.isDigit(e.getLine(2).charAt(x))) {
e.setLine(2, ChatColor.DARK_RED + e.getLine(2));
e.setLine(3, ChatColor.DARK_RED + e.getLine(3));
break;
}
if (x == e.getLine(2).length() - 1) {
List<String> fList = new ArrayList<>();
for (int y = 0; y < dirFile.list().length; y++) {
if (dirFile.listFiles()[y].isFile()) {
fList.add(dirFile.listFiles()[y].getName());
}
}
try {
if (Integer.parseInt(e.getLine(2)) >= 0 && Integer.parseInt(e.getLine(2)) <= fList.size()) {
BooksWithoutBorders.loadList.put(e.getPlayer().getName(), BooksWithoutBorders.bwb.listFiles(e.getPlayer(), true, 0, true));
e.setLine(2, ChatColor.DARK_GREEN + e.getLine(2));
e.setLine(3, ChatColor.DARK_GREEN + e.getLine(3));
} else {
e.setLine(2, ChatColor.DARK_RED + e.getLine(2));
e.setLine(3, ChatColor.DARK_RED + e.getLine(3));
}
} catch (NumberFormatException ignored) {
}
}
}
}
}
} else {
e.setLine(1, ChatColor.DARK_RED + e.getLine(1));
}
}
}
@EventHandler
public void onClick(PlayerInteractEvent e) {
if (e.getClickedBlock() == null) {
return;
}
Material clickedBlockType = e.getClickedBlock().getType();
Player player = e.getPlayer();
PlayerInventory playerInventory = player.getInventory();
EquipmentSlot hand = e.getHand();
if (hand == null) {
return;
}
ItemStack heldItem = playerInventory.getItem(hand);
Material heldItemType = heldItem.getType();
if (e.getAction() == Action.RIGHT_CLICK_BLOCK && (Tag.SIGNS.isTagged(clickedBlockType) || Tag.WALL_SIGNS.isTagged(clickedBlockType))) {
//The player right-clicked a sign
Sign sign = (Sign) e.getClickedBlock().getState();
if (signLineEquals(sign, 0, "[BooksWithoutBorders]", ChatColor.DARK_GREEN)) {
if (signLineEquals(sign, 1, "[Encrypt]", ChatColor.DARK_BLUE)) {
encryptHeldBookUsingSign(sign, heldItemType, player, hand);
} else if (signLineEquals(sign, 1, "[Decrypt]", ChatColor.DARK_BLUE)) {
decryptHeldBookUsingSign(sign, heldItemType, player, hand);
} else if (signLineEquals(sign, 1, "[Give]", ChatColor.DARK_BLUE) &&
getSignLineColor(sign, 2) == ChatColor.DARK_GREEN) {
giveBook(sign, player);
}
}
} else if (heldItemType == Material.WRITTEN_BOOK && (e.getAction() == Action.LEFT_CLICK_AIR
|| e.getAction() == Action.LEFT_CLICK_BLOCK)) {
BookMeta oldBook = (BookMeta) heldItem.getItemMeta();
if (oldBook == null) {
return;
}
decryptBook(oldBook, player, heldItem, hand);
}
}
/**
* Decrypts a book decryptable for a given group
*
* @param oldBook <p>Metadata for the encrypted book</p>
* @param player <p>The player decrypting the book</p>
* @param heldItem <p>The type of the held book</p>
* @param hand <p>The hand the player is using to hold the book</p>
*/
private void decryptBook(BookMeta oldBook, Player player, ItemStack heldItem, EquipmentSlot hand) {
ItemStack newBook;
//Check if the book is encrypted by Books Without Borders
if (!oldBook.hasLore() || oldBook.getLore() == null || !oldBook.getLore().get(0).contains(" encrypted]")) {
return;
}
String groupName = oldBook.getLore().get(0).substring(3).split(" encrypted")[0];
//Permission check
if (!player.hasPermission("bookswithoutborders.decrypt." + groupName) &&
!(BooksWithoutBorders.adminDecrypt && player.hasPermission("bookswithoutborders.admin"))) {
return;
}
String fileName = oldBook.getTitle() + BooksWithoutBorders.titleAuthorSeparator + oldBook.getAuthor();
String encryptionFile = BooksWithoutBorders.bwb.cleanString(groupName) + slash + fileName + ".yml";
File file = new File(bookFolder + "Encrypted" + slash + encryptionFile);
if (!file.isFile()) {
file = new File(bookFolder + fileName + ".txt");
if (!file.isFile()) {
return;
}
}
newBook = BooksWithoutBorders.bwb.loadBook(player, fileName, "true", groupName, heldItem.getAmount());
player.getInventory().setItem(hand, newBook);
player.closeInventory();
player.sendMessage(ChatColor.GREEN + "Book auto-decrypted!");
}
/**
* Encrypts and replaces the player's used book
*
* @param sign <p>The clicked sign</p>
* @param heldItemType <p>The item type used to click the sign</p>
* @param player <p>The player which clicked the sign</p>
* @param hand <p>The EquipmentSlot of the used hand</p>
*/
private void encryptHeldBookUsingSign(Sign sign, Material heldItemType, Player player, EquipmentSlot hand) {
ItemStack eBook;
if (heldItemType == Material.WRITTEN_BOOK) {
player.closeInventory();
eBook = BooksWithoutBorders.bwb.bookEncryption(player, sign.getLine(2).substring(2), sign.getLine(3).substring(2), "");
if (eBook != null) {
player.getInventory().setItem(hand, eBook);
}
}
}
/**
* Gives a player the book specified on a sign
*
* @param sign <p>The sign the user clicked</p>
* @param player <p>The player which clicked the sign</p>
*/
private void giveBook(Sign sign, Player player) {
String fileName = sign.getLine(2).substring(2);
boolean isLoadListNumber = false;
for (int x = 0; x < fileName.length(); x++) {
if (!Character.isDigit(fileName.charAt(x)))
break;
if (x == fileName.length() - 1) {
BooksWithoutBorders.loadList.put(player.getName(), BooksWithoutBorders.bwb.listFiles(player, true, 0, true));
isLoadListNumber = true;
}
}
if (!isLoadListNumber && sign.getLine(3).length() >= 2)
fileName = sign.getLine(2).substring(2) + sign.getLine(3).substring(2);
ItemStack newBook = BooksWithoutBorders.bwb.loadBook(player, fileName, "true", "public");
if (newBook != null) {
player.getInventory().addItem(newBook);
player.sendMessage(ChatColor.GREEN + "Received book!");
} else {
player.sendMessage(ChatColor.RED + "Book failed to load!");
}
}
/**
* Decrypts and replaces the player's used book
*
* @param sign <p>The clicked sign</p>
* @param heldItemType <p>The item type used to click the sign</p>
* @param player <p>The player which clicked the sign</p>
* @param hand <p>The EquipmentSlot of the used hand</p>
*/
private void decryptHeldBookUsingSign(Sign sign, Material heldItemType, Player player, EquipmentSlot hand) {
//Decrypt the held book and replace it
if (heldItemType == Material.WRITTEN_BOOK) {
player.closeInventory();
//Converts user supplied key into integer form
StringBuilder key = new StringBuilder();
String lineText = ChatColor.stripColor(sign.getLine(2));
for (int x = 0; x < lineText.length(); x++) {
key.append(Character.getNumericValue(Character.codePointAt(lineText, x)));
}
ItemStack book = BooksWithoutBorders.bwb.eLoad(player, key.toString(), false);
if (book != null) {
player.getInventory().setItem(hand, book);
player.sendMessage(ChatColor.GREEN + "Book decrypted!");
}
}
}
/**
* Gets the color of a line on a sign
*
* @param sign <p>The sign to check</p>
* @param lineNumber <p>The line number to check</p>
* @return <p>The color of the sign</p>
*/
private ChatColor getSignLineColor(Sign sign, int lineNumber) {
return ChatColor.getByChar(sign.getLine(lineNumber).substring(0, 2));
}
/**
* Checks if a line on a sign equals some string, and that the sign is the correct color
*
* @param sign <p>The sign to read</p>
* @param lineNumber <p>The sign line to read</p>
* @param compareTo <p>The string to look for</p>
* @param color <p>The color to match</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) {
String line = sign.getLine(lineNumber);
return line.equalsIgnoreCase(color + compareTo);
}
}

View File

@ -0,0 +1,170 @@
package net.knarcraft.bookswithoutborders;
import java.util.Random;
import java.util.ArrayList;
import java.util.HashMap;
public class GenenCrypt {
private final Random ranGen;
private final String[] bases;
private final ArrayList<String> originalCodonList;
private final ArrayList<String> shuffledCodonList;
private final String[] charList;
private final HashMap<String,String[]> codonTable;
private final HashMap<String, String> decryptTable;
private final String key;
public GenenCrypt(String key){
// define the initial, unshuffled codon list of 4 base codons
originalCodonList = new ArrayList<>();
bases = new String[]{"A", "T", "G", "C"};
for(int i = 0; i < 4; i++){
for(int j = 0; j < 4; j++){
for(int k = 0; k < 4; k++){
for(int l = 0; l < 4; l++){
originalCodonList.add("" + bases[i] + bases[j] + bases[k] + bases[l]);
}
}
}
}
// make a random number generator with a seed based on the key
this.key = key;
long longKey = 0;
for(int i = 0; i < key.length(); i++){
longKey += (int)key.charAt(i);
}
ranGen = new java.util.Random(longKey);
// use the random number generator and the originalCodonList to make a shuffled list
shuffledCodonList = new ArrayList<>();
while(originalCodonList.size() > 0){
int index = ranGen.nextInt(originalCodonList.size());
shuffledCodonList.add(originalCodonList.get(index));
originalCodonList.remove(index);
}
// define the characters that can be encoded, 64 in total
// 26 capital letters
// 10 digits
// space, newline, and tab
// the symbols . , ? " ! @ # $ % ^ & * ( ) - + = / _ \ : ; < >
charList = new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", " ", "\t", "\n", ".", ",", "?", "\"", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "-", "+", "=", "/", "_", "\\", ":", ";", "<", ">", "|"};
// define the codon table to encode text
codonTable = new HashMap<>();
for(int i = 0; i < charList.length; i++){
String[] tempArray = new String[]{shuffledCodonList.get(4 * i), shuffledCodonList.get(4 * i + 1), shuffledCodonList.get(4 * i + 2), shuffledCodonList.get(4 * i + 3)};
//System.out.println(i);
codonTable.put(charList[i], tempArray);
}
// define the decryption table
decryptTable = new HashMap<>();
for(int i = 0; i < codonTable.size(); i++){
String s = charList[i];
String[] sa = codonTable.get(s);
decryptTable.put(sa[0], s);
decryptTable.put(sa[1], s);
decryptTable.put(sa[2], s);
decryptTable.put(sa[3], s);
}
}
public void printShuffledList(){
for (String s : shuffledCodonList) {
System.out.println(s);
}
}
public void printOriginalList(){
for (String s : originalCodonList) {
System.out.println(s);
}
}
public void printCodonTable(){
// print the codon table
for(int i = 0; i < codonTable.size(); i++){
String s = charList[i];
String[] sa = codonTable.get(s);
switch (s) {
case "\t":
System.out.println(i + "\t" + "\\t" + "\t" + sa[0] + ", " + sa[1] + ", " + sa[2] + ", " + sa[3]);
break;
case "\n":
System.out.println(i + "\t" + "\\n" + "\t" + sa[0] + ", " + sa[1] + ", " + sa[2] + ", " + sa[3]);
break;
case " ":
System.out.println(i + "\t" + "\" \"" + "\t" + sa[0] + ", " + sa[1] + ", " + sa[2] + ", " + sa[3]);
break;
default:
System.out.println(i + "\t" + s + "\t" + sa[0] + ", " + sa[1] + ", " + sa[2] + ", " + sa[3]);
break;
}
}
}
public String encrypt(String input){
StringBuilder output = new StringBuilder();
for(int i = 0; i < input.length(); i++){
// insert junk bases
int offset = key.charAt(i % key.length());
StringBuilder junk = new StringBuilder();
for(int j = 0; j < offset; j++){
junk.append(bases[ranGen.nextInt(4)]);
}
output.append(junk);
int choose = ranGen.nextInt(4);
String s = ("" + input.charAt(i)).toUpperCase();
if(codonTable.containsKey(s)){
String[] sa = codonTable.get(s);
output.append(sa[choose]);
}
}
// add some junk bases to the end of the cipher text
int offset = key.charAt(input.length() % key.length());
StringBuilder junk = new StringBuilder();
for(int j = 0; j < offset; j++){
junk.append(bases[ranGen.nextInt(4)]);
}
output.append(junk);
return output.toString();
}
public String decrypt(String in){
String input = "" + in;
StringBuilder output = new StringBuilder();
int keyCount = 0;
int junk = key.charAt(keyCount % key.length());
while(input.length() > junk){
// cuts out the junk bases
input = input.substring(junk);
// get the codon, decrypt the codon, remove it from the input string
String codon = input.substring(0, 4);
output.append(decryptTable.get(codon));
input = input.substring(4);
// increment the key counter and update junk
keyCount++;
junk = key.charAt(keyCount % key.length());
}
return output.toString();
}
/*public static void main(String[] args){
GenenCrypt gc = new GenenCrypt("Another Key");
gc.printCodonTable();
System.out.println();
System.out.println();
System.out.println();
System.out.println("Encrypting the line \"Hello World!\"");
String encrypted = gc.encrypt("Hello World!");
System.out.println(encrypted);
System.out.println();
System.out.println("Decrypting the ciphertext");
System.out.println(gc.decrypt(encrypted));
}*/
}

View File

@ -0,0 +1,87 @@
package net.knarcraft.bookswithoutborders;
import java.math.BigInteger;
import java.util.StringTokenizer;
public class SubstitutionCipher {
public SubstitutionCipher() {
}
// encrypts a string using a substitution cipher.
// the substitution is made harder to crack by
// using a string for the key, it is converted
// a series of offsets that each character in the
// original message is offset by
public String encrypt(String in, String key) {
StringBuilder output = new StringBuilder();
if (key != null && key.length() > 0) {
StringTokenizer tokenizer = new StringTokenizer(key, ", "); // tokenizes the key
// converts each number in the key to an integer and adds to an array
int[] offsetArray = new int[tokenizer.countTokens()];
for (int i = 0; i < offsetArray.length; i++) {
String nt = tokenizer.nextToken();
try {
offsetArray[i] = Integer.parseInt(nt);
} catch (NumberFormatException e) {
BigInteger big = new BigInteger(nt);
offsetArray[i] = Math.abs(big.intValue());
}
}
int offsetPosition = 0;
for (int i = 0; i < in.length(); i++) {
output.append((char) (in.charAt(i) + offsetArray[offsetPosition])); //encrypts the letter and adds to the output string
// uses the next offset in the key, goes back to first offset if at end of list
if (offsetPosition < offsetArray.length - 1) {
offsetPosition++;
} else {
offsetPosition = 0;
}
}
}
return output.toString();
}
// decrypts a string using the same substitution method,
// but in reverse. Could probably be combined into one
// method with a flag for encryption / decryption, but
// I'm lazy.
public String decrypt(String in, String key) {
StringBuilder output = new StringBuilder();
if (key != null && key.length() > 0) {
StringTokenizer tokenizer = new StringTokenizer(key, ", "); // tokenizes the key
// converts each number in the key to an integer and adds to an array
int[] offsetArray = new int[tokenizer.countTokens()];
for (int i = 0; i < offsetArray.length; i++) {
offsetArray[i] = Integer.parseInt(tokenizer.nextToken());
}
int offsetPosition = 0;
for (int i = 0; i < in.length(); i++) {
output.append((char) (in.charAt(i) - offsetArray[offsetPosition])); //encrypts the letter and adds to the output string
// uses the next offset in the key, goes back to first offset if at end of list
if (offsetPosition < offsetArray.length - 1) {
offsetPosition++;
} else {
offsetPosition = 0;
}
}
}
return output.toString();
}
// the one time pad encryption is very secure, and
// encryption works just like decryption, but is
// vulnerable if the same key is used more than once.
public String oneTimePad(String in, String key) {
StringBuilder output = new StringBuilder();
for (int i = 0; i < in.length(); i++) {
output.append((char) (in.charAt(i) ^ key.charAt(i % key.length())));
}
return output.toString();
}
}

View File

@ -0,0 +1,81 @@
name: Books-Without-Borders
version: '${project.version}'
main: net.knarcraft.bookswithoutborders.bookswithoutborders.BooksWithoutBorders
api-version: 1.17
prefix: Books Without Borders
authors: [ EpicKnarvik97, AkiraAkiba ]
description: A continuation of the original Books Without Borders
softdepend:
- Vault
website: ????
dev-url: ????
commands:
BooksWithoutBorders:
description: Lists Books Without Borders's commands and uses.
aliases: bwb
permissions:
bookswithoutborders.admin:
description: Grants all permissions
default: op
children:
bookswithoutborders.use: true
bookswithoutborders.unsign: true
bookswithoutborders.copy: true
bookswithoutborders.loadpublic: true
bookswithoutborders.savepublic: true
bookswithoutborders.encrypt: true
bookswithoutborders.decrypt: true
bookswithoutborders.signs: true
bookswithoutborders.give: true
bookswithoutborders.givepublic: true
bookswithoutborders.settitle: true
bookswithoutborders.setauthor: true
bookswithoutborders.setlore: true
bookswithoutborders.bypassauthoronlycopy: true
bookswithoutborders.bypassbookprice: true
bookswithoutborders.groupencrypt: true
bookswithoutborders.setbookprice: true
bookswithoutborders.use:
description: Allows player to use commands and to save/load/delete in their personal directory
children:
bookswithoutborders.save: true
bookswithoutborders.load: true
bookswithoutborders.delete: true
bookswithoutborders.save:
description: Allows player to save books to their personal directory
bookswithoutborders.load:
description: Allows player to load books from their personal directory
bookswithoutborders.delete:
description: Allows player to delete books from their personal directory
bookswithoutborders.unsign:
description: Allows player to use unsign command
bookswithoutborders.copy:
description: Allows player to use copy command
bookswithoutborders.loadpublic:
description: Allows player to load in the public directory
bookswithoutborders.savepublic:
description: Allows player to save in the public directory
bookswithoutborders.encrypt:
description: Allows player to encrypt books
bookswithoutborders.groupencrypt:
description: Allows player to set group based encryption
bookswithoutborders.decrypt:
description: Allows player to decrypt books
bookswithoutborders.signs:
description: Allows player to create signs that give/encrypt/decrypt books
bookswithoutborders.give:
description: Allows player to give another player one of their privately saved books
bookswithoutborders.givepublic:
description: Allows player to give another player a book from the public directory
bookswithoutborders.settitle:
description: Allows player to set the title of the currenlty held book
bookswithoutborders.setauthor:
description: Allows player to set the author of the currently held book
bookswithoutborders.setlore:
description: Allows player to set the lore of the currently held item
bookswithoutborders.bypassauthoronlycopy:
description: Allows player to ignore Author_Only_Copy config setting
bookswithoutborders.bypassbookprice:
description: Allows player to ignore Price_to_create_book config setting
bookswithoutborders.setbookprice:
description: Allows player to set the cost of creating a book