diff --git a/.gitignore b/.gitignore index a5772459..dd6896f1 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,6 @@ bin .settings .classpath .project + +# Fabric specific folders +fabric/run/ diff --git a/common/src/main/java/de/sean/blockprot/nbt/IBlockNBTHandler.java b/common/src/main/java/de/sean/blockprot/nbt/IBlockNBTHandler.java new file mode 100644 index 00000000..aa33b393 --- /dev/null +++ b/common/src/main/java/de/sean/blockprot/nbt/IBlockNBTHandler.java @@ -0,0 +1,279 @@ +/* + * Copyright (C) 2021 spnda + * This file is part of BlockProt . + * + * BlockProt is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * BlockProt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with BlockProt. If not, see . + */ + +package de.sean.blockprot.nbt; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * A block handler to get values and settings from a single lockable + * block. + * + * @since 0.2.3 + */ +public abstract class IBlockNBTHandler> extends INBTHandler { + protected static final boolean DEFAULT_REDSTONE = true; + + protected static final String OWNER_ATTRIBUTE = "splugin_owner"; + + protected static final String OLD_LOCK_ATTRIBUTE = "splugin_lock"; + + protected static final String LOCK_ATTRIBUTE = "blockprot_friends"; + + protected static final String REDSTONE_ATTRIBUTE = "splugin_lock_redstone"; + + /** + * Reads the current owner from the NBT container. + * + * @return The owner as a UUID-String read from the container, or an empty String. + * @since 0.2.3 + */ + @NotNull + public abstract String getOwner(); + + /** + * Set the current owner of this block. + * + * @param owner The new owner for this block. Should + * be a valid UUID. + * @since 0.2.3 + */ + public abstract void setOwner(@NotNull final String owner); + + /** + * Gets a {@link Stream} of {@link IFriendHandler} for this block. + * + * @return A stream of friend handlers for all NBT compounds under + * the friend key. + * @since 0.3.0 + */ + @NotNull + public abstract Stream getFriendsStream(); + + /** + * Gets a {@link List} of friends for this block. + * + * @return A list of {@link IFriendHandler} to read + * additional data for each friend. + * @since 0.3.0 + */ + @NotNull + public List getFriends() { + return getFriendsStream().collect(Collectors.toList()); + } + + /** + * Set a new list of FriendHandler for the friends list. + * + * @param access The new list of friends to use. + * @since 0.3.0 + */ + public abstract void setFriends(@NotNull final List access); + + /** + * Filters the results of {@link #getFriends()} for any entry which + * id qualifies for {@link String#equals(Object)}. + * + * @param id The String ID to check for. Usually a UUID as a String as {@link UUID#toString()}. + * @return The first {@link IFriendHandler} found, or none. + * @since 0.3.0 + */ + @NotNull + public Optional getFriend(@NotNull final String id) { + return getFriendsStream() + .filter((f) -> f.getName().equals(id)) + .findFirst(); + } + + /** + * Adds a new friend to the NBT. + * + * @param friend The friend to add. + * @since 0.3.0 + */ + public abstract void addFriend(@NotNull final String friend); + + /** + * Removes a friend from the NBT. + * + * @param friend The friend to remove. + * @since 0.3.0 + */ + public abstract void removeFriend(@NotNull final String friend); + + /** + * If true, redstone should be allowed for this block and should not be blocked. + * If redstone has not been set for this block yet, the default value is true + * + * @return Whether redstone should be allowed or not. + * @since 0.2.3 + */ + public abstract boolean getRedstone(); + + /** + * Set the new value for redstone. See {@link #getRedstone()} for more + * details on the values. + * + * @param redstone The boolean value to set. + * @since 0.2.3 + */ + public abstract void setRedstone(final boolean redstone); + + /** + * This applies any changes to this container to a possible other + * half. For example doors consist from two blocks, as do double + * chests. Without this call, all methods will modify only the local, + * current block. + *

+ * This method is specifically not called on each modification of NBT, + * as this would be a massive, unnecessary performance penalty. + * + * @since 0.4.6 + */ + public abstract void applyToOtherContainer(); + + /** + * Locks this block for given {@code player} as the owner. + * + * @param player The player to set as an owner. + * @return A {@code L} whether or not the block was successfully locked, + * else there might have been issues with permissions. + * @since 0.4.6 + */ + @NotNull + public abstract LockReturnValue lockBlock(@NotNull final K player); + + /** + * Locks redstone for this block. + * + * @param player The player requesting this command, should be the owner. + * @param value The value we want to set it to. If null, we just flip + * the current value. + * @return A {@code L} whether or not the redstone was switched + * successfully. + * @since 0.4.6 + */ + @NotNull + public abstract LockReturnValue lockRedstoneForBlock(@NotNull final String player, @Nullable final Boolean value); + + /** + * Whether or not this block is protected. This is evaluated by checking + * if an owner exists and if any friends have been added to the block. + * + * @return True, if this block is not protected and there is no owner. + * @since 0.2.3 + */ + public boolean isNotProtected() { + return getOwner().isEmpty() && getFriends().isEmpty(); + } + + /** + * @return True, if this block is protected. + * @see #isNotProtected() + * @since 0.2.3 + */ + public boolean isProtected() { + return !isNotProtected(); + } + + /** + * Checks whether or not given {@code player} is the owner of this block. + * + * @param player A String representing a players UUID. + * @return Whether or not {@code player} is the owner of this block. + * @since 0.2.3 + */ + public boolean isOwner(@NotNull final String player) { + return getOwner().equals(player); + } + + /** + * Checks whether or not given {@code player} can access this block. + * + * @param player The player to check for. + * @return True, if {@code player} can access this block. + * @since 0.2.3 + */ + public boolean canAccess(@NotNull final String player) { + Optional friend = getFriend(player); + return !isProtected() || (getOwner().equals(player) || (friend.isPresent() && friend.get().canRead())); + } + + /** + * Checks whether or not {@code friends} contains {@code friend}. + * + * @param friends A list of all friends we want to filter. + * @param friend The UUID of a player we want to check for. + * @return True, if the list does contain that friend. + * @since 0.3.0 + */ + protected boolean containsFriend(@NotNull final List friends, @NotNull final String friend) { + return friends + .stream() + .anyMatch((f) -> f.getName().equals(friend)); + } + + /** + * Clears all values from this block and resets it to the + * defaults. + * + * @since 0.3.2 + */ + public void clear() { + this.setOwner(""); + this.setFriends(Collections.emptyList()); + this.setRedstone(DEFAULT_REDSTONE); + } + + /** + * Modifies the friends of this block for given {@code action}. + * + * @param player The player requesting this command, should be the owner. + * @param friend The friend do to {@code action} with. + * @param action The action we should perform with {@code friend} on this block. + * @return A {@code L} whether or not the friends were modified + * successfully. + * @since 0.4.6 + */ + @NotNull + public abstract LockReturnValue modifyFriends(@NotNull final String player, @NotNull final String friend, @NotNull final FriendModifyAction action); + + /** + * Merges this handler with another {@link INBTHandler}. + * + * @param handler The handler to merge with. If {@code handler} is not an instance + * of {@link IBlockNBTHandler}, this will do nothing. + * @since 0.3.2 + */ + @Override + public void mergeHandler(@NotNull INBTHandler handler) { + if (!(handler instanceof IBlockNBTHandler)) return; + final IBlockNBTHandler blockNBTHandler = (IBlockNBTHandler) handler; + this.setOwner(blockNBTHandler.getOwner()); + this.setFriends(blockNBTHandler.getFriends()); + this.setRedstone(blockNBTHandler.getRedstone()); + } +} diff --git a/common/src/main/java/de/sean/blockprot/nbt/IFriendHandler.java b/common/src/main/java/de/sean/blockprot/nbt/IFriendHandler.java new file mode 100644 index 00000000..007b5724 --- /dev/null +++ b/common/src/main/java/de/sean/blockprot/nbt/IFriendHandler.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2021 spnda + * This file is part of BlockProt . + * + * BlockProt is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * BlockProt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with BlockProt. If not, see . + */ + +package de.sean.blockprot.nbt; + +import org.jetbrains.annotations.NotNull; + +import java.util.EnumSet; + +/** + * The friend handler used by {@link IBlockNBTHandler} to handle + * each of the nbt compounds used in the "friends" sub-tag of each block. + * A single {@link IFriendHandler} itself only handles a *single friend* + * in the list of friends. + * + * @since 0.3.0 + */ +public abstract class IFriendHandler> extends INBTHandler { + protected static final String ACCESS_FLAGS_ATTRIBUTE = "blockprot_access_flags"; + + private final String name; + + protected IFriendHandler(@NotNull final String name) { + this.name = name; + } + + @Override + @NotNull + public String getName() { + return name; + } + + /** + * Read the access flags of this block as a bitset. + * + * @return A bitset of all access flags of this block. + * @see #getAccessFlags() + * @since 0.4.7 + */ + protected abstract int getAccessFlagsBitset(); + + /** + * Sets the access flag bitset for this block. + * + * @param bitset The new bitset. + * @since 0.4.7 + */ + protected abstract void setAccessFlagsBitset(final int bitset); + + /** + * Read the access flags of this block. + * + * @return A {@link EnumSet} of all flags for this block. + * @since 0.3.0 + */ + @NotNull + public abstract EnumSet getAccessFlags(); + + /** + * Sets the access flags for this block. ORs all flags together to one integer, then + * writes all of them to ACCESS_FLAGS_ATTRIBUTE. + * + * @param flags The new flags to use. These get converted to integers. + * @since 0.3.0 + */ + public abstract void setAccessFlags(@NotNull final EnumSet flags); + + /** + * Checks if this player can read the contents of the parents + * block. + * + * @return True, if the player is allowed to see the container's + * contents. + * @since 0.3.0 + */ + public abstract boolean canRead(); + + /** + * Checks if this player can write the contents of the parents + * block. This means that the player should be allowed to + * take and add items at their will. + * + * @return True, if the player has write access to this block. + * @since 0.3.0 + */ + public abstract boolean canWrite(); + + /** + * {@inheritDoc} + *

+ * This only merges values if {@code handler} is an instance of {@link IFriendHandler}, + * and only merges the access flags. + * + * @since 0.4.7 + */ + @Override + public void mergeHandler(@NotNull INBTHandler handler) { + if (handler instanceof IFriendHandler) { + this.setAccessFlagsBitset(((IFriendHandler) handler).getAccessFlagsBitset()); + } + } +} diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/nbt/NBTHandler.java b/common/src/main/java/de/sean/blockprot/nbt/INBTHandler.java similarity index 60% rename from spigot/src/main/java/de/sean/blockprot/bukkit/nbt/NBTHandler.java rename to common/src/main/java/de/sean/blockprot/nbt/INBTHandler.java index b51782df..321a967b 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/nbt/NBTHandler.java +++ b/common/src/main/java/de/sean/blockprot/nbt/INBTHandler.java @@ -16,29 +16,20 @@ * along with BlockProt. If not, see . */ -package de.sean.blockprot.bukkit.nbt; +package de.sean.blockprot.nbt; -import de.tr7zw.changeme.nbtapi.NBTCompound; import org.jetbrains.annotations.NotNull; /** * The base NBT Handler. * - * @param The type of the NBT container. {@link NBTCompound} - * is the base of all containers and works with all of them, - * however there are some special conditions and functions - * for specific containers. + * @param The type of the NBT container. A NBT compound should the + * base of all containers and works with all of them, however + * there are some special conditions and functions for specific + * containers. * @since 0.3.0 */ -public abstract class NBTHandler { - public static final String PERMISSION_LOCK = "blockprot.lock"; - - public static final String PERMISSION_INFO = "blockprot.info"; - - public static final String PERMISSION_ADMIN = "blockprot.admin"; - - public static final String PERMISSION_BYPASS = "blockprot.bypass"; - +public abstract class INBTHandler { /** * The NBT container for this handler. * @@ -51,7 +42,18 @@ public abstract class NBTHandler { * * @since 0.3.0 */ - protected NBTHandler() { + protected INBTHandler() { + } + + /** + * Get a copy of the underlying NBT container. + * + * @return The NBT container. + * @since 0.4.7 + */ + @NotNull + public T getContainer() { + return container; } /** @@ -61,10 +63,7 @@ protected NBTHandler() { * @since 0.4.4 */ @NotNull - public String getName() { - String name = container.getName(); - return name == null ? "" : name; - } + public abstract String getName(); /** * Copies all values of the other handler to this handler. @@ -72,5 +71,5 @@ public String getName() { * @param handler The handler to copy values from. * @since 0.3.2 */ - public abstract void mergeHandler(@NotNull final NBTHandler handler); + public abstract void mergeHandler(@NotNull final INBTHandler handler); } diff --git a/common/src/main/java/de/sean/blockprot/nbt/IPlayerSettingsHandler.java b/common/src/main/java/de/sean/blockprot/nbt/IPlayerSettingsHandler.java new file mode 100644 index 00000000..f4add5d5 --- /dev/null +++ b/common/src/main/java/de/sean/blockprot/nbt/IPlayerSettingsHandler.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2021 spnda + * This file is part of BlockProt . + * + * BlockProt is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * BlockProt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with BlockProt. If not, see . + */ + +package de.sean.blockprot.nbt; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.UUID; + +/** + * A simple handler to get a player's BlockProt settings. + * + * @since 0.2.3 + */ +public abstract class IPlayerSettingsHandler extends INBTHandler { + protected static final String LOCK_ON_PLACE_ATTRIBUTE = "splugin_lock_on_place"; + + protected static final String DEFAULT_FRIENDS_ATTRIBUTE = "blockprot_default_friends"; + + protected static final String PLAYER_SEARCH_HISTORY = "blockprot_player_search_history"; + + /** + * The player that this settings handler is getting values + * for. + * + * @since 0.2.3 + */ + public final P player; + + protected IPlayerSettingsHandler(@NotNull final P player) { + this.player = player; + } + + /** + * Check if the player wants their blocks to be locked when + * placed. + * + * @return Returns true, if lock on place has not been set, otherwise + * will return the player's setting. + * @since 0.2.3 + */ + public abstract boolean getLockOnPlace(); + + /** + * Set the value of the lock on place setting. If true, the + * player wants to lock any block right after placing it. + * + * @param value The boolean value to set it to. + * @since 0.2.3 + */ + public abstract void setLockOnPlace(final boolean value); + + /** + * Get the {@link List} of default friends for this player. + * + * @return A List of Player {@link UUID}s as {@link String}s + * representing each friend. + * @since 0.2.3 + */ + @NotNull + public abstract List getDefaultFriends(); + + + /** + * Set a new list of default friends. These have to be UUID-based, + * otherwise other callers using {@link #getDefaultFriends()} will + * experience issues. This does not get checked. + * + * @param friends A list of UUIDs representing a list of friends. + * @since 0.2.3 + */ + public abstract void setDefaultFriends(@NotNull final List friends); + + /** + * Gets the default friends as a list of {@code P}. Uses + * {@link #getDefaultFriends} as a base. + * + * @return All default friends as a list of {@code P}. + * @since 0.2.3 + */ + @NotNull + public abstract List

getDefaultFriendsAsPlayers(); +} diff --git a/common/src/main/java/de/sean/blockprot/screens/BlockProtScreen.java b/common/src/main/java/de/sean/blockprot/screens/BlockProtScreen.java new file mode 100644 index 00000000..e58799b5 --- /dev/null +++ b/common/src/main/java/de/sean/blockprot/screens/BlockProtScreen.java @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2021 spnda + * This file is part of BlockProt . + * + * BlockProt is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * BlockProt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with BlockProt. If not, see . + */ + +package de.sean.blockprot.screens; + +/** + * Interface with base methods for any inventory screen. + * + * @param The type of ItemStack. + * @param The translation key class. + */ +public interface BlockProtScreen { + /** + * Get the default size of a single row. This defaults to 9, the width + * of a chest, barrel and most other "menu" screens. Can be overridden + * to have a container similar to a dispenser or hopper. + * + * @return By default the size of a single row, 9. + */ + default int getRowSize() { + return 9; + } + + /** + * Gets the complete size of the inventory, multiplying {@link #getRowSize()} + * with {@link #getRows()}. + * + * @return The complete size of the inventory. + */ + default int getSize() { + return getRowSize() * getRows(); + } + + /** + * Get the size of this inventory, which should be a multiple of 9 with a maximum value of 6 * + * 9. + * + * @return The size of this inventory. + * @since 0.2.2 + */ + int getRows(); + + /** + * Get the default inventory name. + * + * @return The translated inventory name, or this class's simple name if the translation was not + * found. + */ + String getDefaultScreenName(); + + /** + * Sets the back button to the last item in the inventory. + * + * @since 0.2.3 + */ + void setBackButton(); + + /** + * Sets the back button to the [index] in the inventory. + * + * @param index The index of the back button inside this inventory. + * @since 0.2.3 + */ + void setBackButton(int index); + + /** + * Sets a ItemStack {@code item} at {@code index}. + * + * @param index The index of the item inside this inventory. + * @param item The item. + * @since 0.2.3 + */ + void setItemStack(int index, I item); + + /** + * Sets a ItemStack with the type [material] and the name translated by [key] at [index]. + * + * @param index The index of the item inside this inventory. + * @param item The material of the item. + * @param key The translation key to use to get the translated name for this item. + * @since 0.2.3 + */ + void setItemStack(int index, I item, T key); + + /** + * Sets a ItemStack with the type {@code material} and the name as {@code text} at {@code index}. + * + * @param index The index of the item inside this inventory. + * @param item The material of the item. + * @param text The text or name of the item. + * @since 0.4.0 + */ + void setItemStack(int index, I item, String text); +} diff --git a/common/src/main/java/de/sean/blockprot/util/BlockProtUtil.java b/common/src/main/java/de/sean/blockprot/util/BlockProtUtil.java index c5ab3c5a..da65062e 100644 --- a/common/src/main/java/de/sean/blockprot/util/BlockProtUtil.java +++ b/common/src/main/java/de/sean/blockprot/util/BlockProtUtil.java @@ -46,4 +46,4 @@ public static List parseStringList(@Nullable final String stringList) { ret.removeIf(String::isEmpty); return ret; } -} \ No newline at end of file +} diff --git a/fabric/build.gradle.kts b/fabric/build.gradle.kts new file mode 100644 index 00000000..c90f483b --- /dev/null +++ b/fabric/build.gradle.kts @@ -0,0 +1,43 @@ +plugins { + id("fabric-loom") version("0.9-SNAPSHOT") + id("com.matthewprenger.cursegradle") version "1.4.0" +} + +repositories { + maven("https://maven.fabricmc.net/") { + name = "Fabric" + } + maven("https://maven.nucleoid.xyz") +} + +dependencies { + implementation(project(":common")) + + // To change the versions see the gradle.properties file + minecraft("com.mojang:minecraft:1.17.1") + mappings("net.fabricmc:yarn:1.17.1+build.30:v2") + modImplementation("net.fabricmc:fabric-loader:0.11.6") + + // Fabric API. This is technically optional, but you probably want it anyway. + modImplementation("net.fabricmc.fabric-api:fabric-api:0.37.1+1.17") + + // sgui library we use for making the server side menu GUIs. + modImplementation("eu.pb4:sgui:1.0.0-rc4+1.17.1") +} + +loom { + accessWidenerPath.set(file("${project.projectDir}/src/main/resources/blockprot.accesswidener")) +} + +tasks.processResources { + inputs.property("version", project.version) + + filesMatching("fabric.mod.json") { + expand("version" to project.version) + } +} + +tasks.compileJava { + java.sourceCompatibility = JavaVersion.VERSION_16 + java.targetCompatibility = JavaVersion.VERSION_16 +} diff --git a/fabric/src/main/java/de/sean/blockprot/fabric/BlockProt.java b/fabric/src/main/java/de/sean/blockprot/fabric/BlockProt.java new file mode 100644 index 00000000..35995245 --- /dev/null +++ b/fabric/src/main/java/de/sean/blockprot/fabric/BlockProt.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2021 spnda + * This file is part of BlockProt . + * + * BlockProt is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * BlockProt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with BlockProt. If not, see . + */ + +package de.sean.blockprot.fabric; + +import net.fabricmc.api.DedicatedServerModInitializer; + +public class BlockProt implements DedicatedServerModInitializer { + public static final String MOD_ID = "blockprot"; + + // public static ScreenHandlerType LOCK_SCREEN_HANDLER; + + @Override + public void onInitializeServer() { + // LOCK_SCREEN_HANDLER = ScreenHandlerRegistry.registerSimple(new Identifier(MOD_ID, "lock"), BlockLockScreen::new); + + // UseBlockCallback.EVENT.register(new BlockCallbackListener()); + + /*BlockPlaceEvent.EVENT.register((livingEntity, pos, block) -> { + Logger.getLogger(BlockProt.class.getSimpleName()).info("Block placed: " + block.toString()); + if (block.getBlock() instanceof BlockWithEntity && livingEntity instanceof PlayerEntity player) { + var settingsHandler = new PlayerSettingsHandler(player); + if (settingsHandler.getLockOnPlace()) { + BlockEntity entity = livingEntity.world.getBlockEntity(pos); + if (entity == null) return ActionResult.PASS; + + // Finally, copy over the default values. + var blockHandler = new BlockNBTHandler(entity); + blockHandler.lockBlock(player); + List friends = settingsHandler.getDefaultFriends(); + for (String friend : friends) { + blockHandler.addFriend(friend); + } + Logger.getLogger(BlockProt.class.getSimpleName()).info("Locked block!"); + } + } + return ActionResult.PASS; + }); + + UseItemCallback.EVENT.register((player, world, hand) -> { + var item = player.getStackInHand(hand); + if (item.getItem() instanceof BlockItem) { + // Only check for items being placed. + var settingsHandler = new PlayerSettingsHandler(player); + if (settingsHandler.getLockOnPlace()) { + + } + } + return TypedActionResult.pass(item); + });*/ + } +} diff --git a/fabric/src/main/java/de/sean/blockprot/fabric/events/BlockPlaceEvent.java b/fabric/src/main/java/de/sean/blockprot/fabric/events/BlockPlaceEvent.java new file mode 100644 index 00000000..f3918bbd --- /dev/null +++ b/fabric/src/main/java/de/sean/blockprot/fabric/events/BlockPlaceEvent.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2021 spnda + * This file is part of BlockProt . + * + * BlockProt is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * BlockProt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with BlockProt. If not, see . + */ + +package de.sean.blockprot.fabric.events; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.block.BlockState; +import net.minecraft.entity.LivingEntity; +import net.minecraft.util.ActionResult; +import net.minecraft.util.math.BlockPos; + +public interface BlockPlaceEvent { + Event EVENT = EventFactory.createArrayBacked(BlockPlaceEvent.class, + (listeners) -> (player, pos, block) -> { + for (BlockPlaceEvent listener : listeners) { + ActionResult result = listener.interact(player, pos, block); + + if (result != ActionResult.PASS) { + return result; + } + } + + return ActionResult.PASS; + }); + + ActionResult interact(LivingEntity player, BlockPos pos, BlockState block); +} diff --git a/fabric/src/main/java/de/sean/blockprot/fabric/ext/BlockEntityNbtExtension.java b/fabric/src/main/java/de/sean/blockprot/fabric/ext/BlockEntityNbtExtension.java new file mode 100644 index 00000000..700e7b69 --- /dev/null +++ b/fabric/src/main/java/de/sean/blockprot/fabric/ext/BlockEntityNbtExtension.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 spnda + * This file is part of BlockProt . + * + * BlockProt is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * BlockProt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with BlockProt. If not, see . + */ + +package de.sean.blockprot.fabric.ext; + +import net.minecraft.nbt.NbtCompound; + +/** + * Mixin accessor used to get NBT values from a block entity. + * Used by {@link de.sean.blockprot.fabric.mixin.MixinBlockEntity}. + */ +public interface BlockEntityNbtExtension { + boolean contains(String key); + + boolean getBoolean(String key); + + void putBoolean(String key, boolean value); + + String getString(String key); + + void putString(String key, String value); + + NbtCompound getCompound(String key); +} diff --git a/fabric/src/main/java/de/sean/blockprot/fabric/ext/PlayerEntityNbtExtension.java b/fabric/src/main/java/de/sean/blockprot/fabric/ext/PlayerEntityNbtExtension.java new file mode 100644 index 00000000..7cb807b5 --- /dev/null +++ b/fabric/src/main/java/de/sean/blockprot/fabric/ext/PlayerEntityNbtExtension.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2021 spnda + * This file is part of BlockProt . + * + * BlockProt is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * BlockProt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with BlockProt. If not, see . + */ + +package de.sean.blockprot.fabric.ext; + +/** + * Mixin accessor used to get NBT values from a player Entity. + * Used by {@link de.sean.blockprot.fabric.mixin.MixinPlayerEntity}. + */ +public interface PlayerEntityNbtExtension { + boolean contains(String key); + + boolean getBoolean(String key); + + void putBoolean(String key, boolean value); + + String getString(String key); + + void putString(String key, String value); +} diff --git a/fabric/src/main/java/de/sean/blockprot/fabric/listeners/BlockCallbackListener.java b/fabric/src/main/java/de/sean/blockprot/fabric/listeners/BlockCallbackListener.java new file mode 100644 index 00000000..8590e337 --- /dev/null +++ b/fabric/src/main/java/de/sean/blockprot/fabric/listeners/BlockCallbackListener.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2021 spnda + * This file is part of BlockProt . + * + * BlockProt is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * BlockProt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with BlockProt. If not, see . + */ + +package de.sean.blockprot.fabric.listeners; + +import de.sean.blockprot.fabric.nbt.BlockNBTHandler; +import de.sean.blockprot.fabric.screens.BlockLockScreen; +import net.fabricmc.fabric.api.event.player.UseBlockCallback; +import net.minecraft.block.ChestBlock; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.world.World; + +import java.util.logging.Logger; + +public class BlockCallbackListener implements UseBlockCallback { + @Override + public ActionResult interact(PlayerEntity player, World world, Hand hand, BlockHitResult hitResult) { + if (player.isSpectator()) return ActionResult.PASS; + var entity = world.getBlockEntity(hitResult.getBlockPos()); + + if (entity != null && entity.getCachedState().getBlock() instanceof ChestBlock) { + var blockHandler = new BlockNBTHandler(entity); + + if (!blockHandler.canAccess(player.getUuidAsString())) { + return ActionResult.FAIL; + } else { + Logger.getLogger(this.getClass().getSimpleName()).info("Can access chest!"); + + if (player.isSneaking() && player instanceof ServerPlayerEntity serverPlayer) { + new BlockLockScreen(serverPlayer).open(); + return ActionResult.FAIL; + } + } + } + return ActionResult.PASS; + } +} diff --git a/fabric/src/main/java/de/sean/blockprot/fabric/mixin/MixinBlock.java b/fabric/src/main/java/de/sean/blockprot/fabric/mixin/MixinBlock.java new file mode 100644 index 00000000..8d96980c --- /dev/null +++ b/fabric/src/main/java/de/sean/blockprot/fabric/mixin/MixinBlock.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2021 spnda + * This file is part of BlockProt . + * + * BlockProt is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * BlockProt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with BlockProt. If not, see . + */ + +package de.sean.blockprot.fabric.mixin; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.entity.LivingEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(Block.class) +public class MixinBlock { + @Inject(at = @At("HEAD"), method = "onPlaced", cancellable = true) + public void onBlockPlaced(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack itemStack, CallbackInfo ci) { + // var result = BlockPlaceEvent.EVENT.invoker().interact(placer, pos, state); + + //if (result != ActionResult.PASS) { + // ci.cancel(); + //} + } +} diff --git a/fabric/src/main/java/de/sean/blockprot/fabric/mixin/MixinBlockEntity.java b/fabric/src/main/java/de/sean/blockprot/fabric/mixin/MixinBlockEntity.java new file mode 100644 index 00000000..afa9d013 --- /dev/null +++ b/fabric/src/main/java/de/sean/blockprot/fabric/mixin/MixinBlockEntity.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2021 spnda + * This file is part of BlockProt . + * + * BlockProt is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * BlockProt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with BlockProt. If not, see . + */ + +package de.sean.blockprot.fabric.mixin; + +import de.sean.blockprot.fabric.ext.BlockEntityNbtExtension; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.nbt.NbtCompound; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(BlockEntity.class) +public class MixinBlockEntity implements BlockEntityNbtExtension { + @Unique + @Final + private static final String NBT_BASE_KEY = "blockprot_nbt"; + + @Mutable + @Unique + private NbtCompound customNbt = new NbtCompound(); + + /** + * Write to the NBT just before returning it. + */ + @Inject(method = "writeNbt", at = @At("RETURN")) + private void writeToNbt(NbtCompound nbt, CallbackInfoReturnable cir) { + nbt.put(NBT_BASE_KEY, customNbt); + } + + /** + * Read from the nbt. + */ + @Inject(method = "readNbt", at = @At("RETURN")) + private void readFromNbt(NbtCompound tag, CallbackInfo ci) { + customNbt = tag.getCompound(NBT_BASE_KEY); + } + + @Override + public boolean contains(String key) { + return customNbt.contains(key); + } + + @Override + public boolean getBoolean(String key) { + return customNbt.getBoolean(key); + } + + @Override + public void putBoolean(String key, boolean value) { + customNbt.putBoolean(key, value); + } + + @Override + public String getString(String key) { + return customNbt.getString(key); + } + + @Override + public void putString(String key, String value) { + customNbt.putString(key, value); + } + + @Override + public NbtCompound getCompound(String key) { + return customNbt.getCompound(key); + } +} diff --git a/fabric/src/main/java/de/sean/blockprot/fabric/mixin/MixinPlayerEntity.java b/fabric/src/main/java/de/sean/blockprot/fabric/mixin/MixinPlayerEntity.java new file mode 100644 index 00000000..e31ba271 --- /dev/null +++ b/fabric/src/main/java/de/sean/blockprot/fabric/mixin/MixinPlayerEntity.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2021 spnda + * This file is part of BlockProt . + * + * BlockProt is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * BlockProt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with BlockProt. If not, see . + */ + +package de.sean.blockprot.fabric.mixin; + +import de.sean.blockprot.fabric.ext.PlayerEntityNbtExtension; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.nbt.NbtCompound; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(PlayerEntity.class) +public class MixinPlayerEntity implements PlayerEntityNbtExtension { + @Unique + @Final + private static final String NBT_BASE_KEY = "blockprot_nbt"; + + /** + * A NBT Compound holding custom NBT data for this player. We + * save this data to a sub-key, {@link #NBT_BASE_KEY}. + */ + @Mutable + @Unique + private NbtCompound customNbt = new NbtCompound(); + + @Inject(method = "writeCustomDataToNbt", at = @At("RETURN")) + private void writeToNbt(NbtCompound nbt, CallbackInfo ci) { + nbt.put(NBT_BASE_KEY, customNbt); + } + + @Inject(method = "readCustomDataFromNbt", at = @At("HEAD")) + private void readFromNbt(NbtCompound tag, CallbackInfo ci) { + customNbt = tag.getCompound(NBT_BASE_KEY); + } + + public boolean contains(String key) { + return customNbt.contains(key); + } + + public boolean getBoolean(String key) { + return customNbt.getBoolean(key); + } + + public void putBoolean(String key, boolean value) { + customNbt.putBoolean(key, value); + } + + public String getString(String key) { + return customNbt.getString(key); + } + + public void putString(String key, String value) { + customNbt.putString(key, value); + } +} diff --git a/fabric/src/main/java/de/sean/blockprot/fabric/nbt/BlockAccessFlag.java b/fabric/src/main/java/de/sean/blockprot/fabric/nbt/BlockAccessFlag.java new file mode 100644 index 00000000..fb18153f --- /dev/null +++ b/fabric/src/main/java/de/sean/blockprot/fabric/nbt/BlockAccessFlag.java @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2021 spnda + * This file is part of BlockProt . + * + * BlockProt is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * BlockProt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with BlockProt. If not, see . + */ + +package de.sean.blockprot.fabric.nbt; + +import de.sean.blockprot.fabric.translation.TranslationIdentifier; +import net.minecraft.text.TranslatableText; +import org.jetbrains.annotations.NotNull; + +import java.util.*; + +/** + * @since 0.2.3 + */ +public enum BlockAccessFlag { + /** + * The user is allowed to see, but not alter, the contents of the inventory. + * + * @since 0.2.3 + */ + READ(TranslationIdentifier.SCREEN_FRIENDS_PERMISSION_READ), + + /** + * The user is allowed to add and remove contents of the inventory. + * + * @since 0.2.3 + */ + WRITE(TranslationIdentifier.SCREEN_FRIENDS_PERMISSION_WRITE); + + /** + * The translation key used for the description of this flag. + * + * @since 0.2.3 + */ + @NotNull + private final TranslationIdentifier descriptionKey; + + /** + * @since 0.2.3 + */ + BlockAccessFlag(@NotNull final TranslationIdentifier description) { + this.descriptionKey = description; + } + + /** + * Parse flags from a single int value. This is done at a binary level. They are + * parsed from their value from {@link BlockAccessFlag#getFlag()}. + * + * @param value The integer to parse from. + * @return A {@link EnumSet} with all flags that were parsed from + * given integer. + * @since 0.2.3 + */ + public static EnumSet parseFlags(final int value) { + EnumSet flags = EnumSet.noneOf(BlockAccessFlag.class); + + final BlockAccessFlag[] values = BlockAccessFlag.values(); + String digits = Integer.toString(value, 2); + for (int i = digits.length() - 1; i >= 0; --i) { + char j = digits.charAt(i); // the bit to check + if (j == '0') { + // only add the flag if it is 1 + continue; + } + int k = digits.length() - 1 - i; // the ordinal of the enum, as per #getFlag + if (k < values.length) { + flags.add(values[k]); + } + } + + return flags; + } + + /** + * Turns a {@link EnumSet} of {@link BlockAccessFlag} into a user-friendly String. + * + * @param flags The flags which are then called {@link String#toString()} on and + * concatenated together into a user-friendly list. + * @return A String of concatenated flags. + * @since 0.3.0 + */ + @NotNull + public static String accessFlagToString(@NotNull final EnumSet flags) { + if (flags.isEmpty()) return "No access"; + StringBuilder builder = new StringBuilder(); + int i = 0; + for (BlockAccessFlag flag : flags) { + String flagStr = flag.toString(); + builder + //.append(ChatColor.ITALIC) + .append(flagStr.substring(0, 1).toUpperCase(Locale.ENGLISH)) // Uppercase first letter. + .append(flagStr.substring(1).toLowerCase(Locale.ENGLISH)); + if (i < (flags.size() - 1)) { + //builder.append(ChatColor.RESET).append(", "); + } + i++; + } + return builder.toString(); + } + + /** + * Accumulate the access flag details into a list of strings, where each entry + * represents a line. Used for item lore in the GUI. + * + * @param flags A {@link EnumSet} of flags to convert. + * @return List of strings used for item lore. + * @since 0.3.0 + */ + @NotNull + public static List accumulateAccessFlagLore(@NotNull final EnumSet flags) { + if (flags.isEmpty()) return Collections.singletonList("No access"); + ArrayList ret = new ArrayList<>(); + StringBuilder builder = new StringBuilder(); + for (BlockAccessFlag flag : flags) { + builder.setLength(0); + builder + //.append(ChatColor.RESET) + //.append(ChatColor.YELLOW) + .append(flag.getDescription()); + ret.add(builder.toString()); + } + return ret; + } + + /** + * Get the translated description of this flag. + * + * @return Translated description. + * @since 0.2.3 + */ + @NotNull + public TranslatableText getDescription() { + return this.descriptionKey.asTranslatableText(); + } + + /** + * Gets this enum as a bit flag. + * + * @return Single bit representing this flag. + * @since 0.2.3 + */ + public int getFlag() { + return 1 << ordinal(); + } +} diff --git a/fabric/src/main/java/de/sean/blockprot/fabric/nbt/BlockNBTHandler.java b/fabric/src/main/java/de/sean/blockprot/fabric/nbt/BlockNBTHandler.java new file mode 100644 index 00000000..2d3cd852 --- /dev/null +++ b/fabric/src/main/java/de/sean/blockprot/fabric/nbt/BlockNBTHandler.java @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2021 spnda + * This file is part of BlockProt . + * + * BlockProt is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * BlockProt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with BlockProt. If not, see . + */ + +package de.sean.blockprot.fabric.nbt; + +import de.sean.blockprot.fabric.ext.BlockEntityNbtExtension; +import de.sean.blockprot.fabric.util.PlayerUtil; +import de.sean.blockprot.nbt.FriendModifyAction; +import de.sean.blockprot.nbt.IBlockNBTHandler; +import de.sean.blockprot.nbt.IFriendHandler; +import de.sean.blockprot.nbt.LockReturnValue; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.nbt.NbtCompound; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.stream.Stream; + +public final class BlockNBTHandler extends IBlockNBTHandler { + public final BlockEntity block; + + public BlockNBTHandler(@NotNull final BlockEntity block) { + this.block = block; + + this.container = (BlockEntityNbtExtension) block; + } + + @Override + public @NotNull String getOwner() { + if (!container.contains(OWNER_ATTRIBUTE)) return ""; + else return container.getString(OWNER_ATTRIBUTE); + } + + @Override + public void setOwner(@NotNull String owner) { + container.putString(OWNER_ATTRIBUTE, owner); + } + + @Override + public @NotNull Stream getFriendsStream() { + if (!container.contains(LOCK_ATTRIBUTE)) return Stream.empty(); + + final var compound = container.getCompound(LOCK_ATTRIBUTE); + return compound + .getKeys() + .stream() + .map((k) -> new FriendHandler(k, compound.getCompound(k))); + } + + @Override + public void setFriends(@NotNull List access) { + final var compound = container.getCompound(LOCK_ATTRIBUTE); + for (IFriendHandler handler : access) { + var oldCompound = ((NbtCompound) handler.getContainer()); + var newCompound = new NbtCompound(); + for (var key : oldCompound.getKeys()) + newCompound.put(key, oldCompound); + compound.put(handler.getName(), newCompound); + } + } + + @Override + public void addFriend(@NotNull String friend) { + var compound = new NbtCompound(); + compound.putString("id", friend); + container.getCompound(LOCK_ATTRIBUTE).put(friend, compound); + } + + @Override + public void removeFriend(@NotNull String friend) { + container.getCompound(LOCK_ATTRIBUTE).remove(friend); + } + + @Override + public boolean getRedstone() { + // We will default to 'true'. The default value for a boolean is 'false', + // which would also be the default value for NBTCompound#getBoolean + if (!container.contains(REDSTONE_ATTRIBUTE)) { + container.putBoolean(REDSTONE_ATTRIBUTE, DEFAULT_REDSTONE); + return DEFAULT_REDSTONE; + } + return container.getBoolean(REDSTONE_ATTRIBUTE); + } + + @Override + public void setRedstone(boolean redstone) { + container.putBoolean(REDSTONE_ATTRIBUTE, redstone); + } + + @Override + public void applyToOtherContainer() { + // TODO: Properly apply to double chests. + } + + @Override + public @NotNull LockReturnValue lockBlock(@NotNull PlayerEntity player) { + var owner = getOwner(); + final var playerUuid = player.getUuidAsString(); + + if (owner.isEmpty()) { + // This block is not owned by anyone, this user can claim this block + owner = playerUuid; + setOwner(owner); + this.applyToOtherContainer(); + return new LockReturnValue(true); + } else if (owner.equals(playerUuid) || PlayerUtil.isOp(player)) { + this.clear(); + this.applyToOtherContainer(); + return new LockReturnValue(true); + } + return new LockReturnValue(false); + } + + @Override + public @NotNull LockReturnValue lockRedstoneForBlock(@NotNull String player, @Nullable Boolean value) { + return null; + } + + @Override + public @NotNull LockReturnValue modifyFriends(@NotNull String player, @NotNull String friend, @NotNull FriendModifyAction action) { + return null; + } + + @Override + public @NotNull String getName() { + return ""; + } +} diff --git a/fabric/src/main/java/de/sean/blockprot/fabric/nbt/FriendHandler.java b/fabric/src/main/java/de/sean/blockprot/fabric/nbt/FriendHandler.java new file mode 100644 index 00000000..e4b6b328 --- /dev/null +++ b/fabric/src/main/java/de/sean/blockprot/fabric/nbt/FriendHandler.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2021 spnda + * This file is part of BlockProt . + * + * BlockProt is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * BlockProt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with BlockProt. If not, see . + */ + +package de.sean.blockprot.fabric.nbt; + +import de.sean.blockprot.nbt.IFriendHandler; +import net.minecraft.nbt.NbtCompound; +import org.jetbrains.annotations.NotNull; + +import java.util.EnumSet; + +public class FriendHandler extends IFriendHandler { + FriendHandler(@NotNull final String name, @NotNull final NbtCompound compound) { + super(name); + this.container = compound; + } + + @Override + protected int getAccessFlagsBitset() { + if (!container.contains(ACCESS_FLAGS_ATTRIBUTE)) return BlockAccessFlag.READ.getFlag() | BlockAccessFlag.WRITE.getFlag(); + else return container.getInt(ACCESS_FLAGS_ATTRIBUTE); + } + + @Override + protected void setAccessFlagsBitset(final int bitset) { + container.putInt(ACCESS_FLAGS_ATTRIBUTE, bitset); + } + + @Override + public @NotNull EnumSet getAccessFlags() { + // We don't just use #getAccessFlagsBitset, as it would have a minor overhead due to + // using the BlockAccessFlag#parseFlags method. + if (!container.contains(ACCESS_FLAGS_ATTRIBUTE)) return EnumSet.of(BlockAccessFlag.READ, BlockAccessFlag.WRITE); + else return BlockAccessFlag.parseFlags(container.getInt(ACCESS_FLAGS_ATTRIBUTE)); + } + + @Override + public void setAccessFlags(@NotNull EnumSet flags) { + container.putInt(ACCESS_FLAGS_ATTRIBUTE, flags.stream().mapToInt(BlockAccessFlag::getFlag).sum()); + } + + @Override + public boolean canRead() { + return getAccessFlags().contains(BlockAccessFlag.READ); + } + + @Override + public boolean canWrite() { + return getAccessFlags().contains(BlockAccessFlag.WRITE); + } +} diff --git a/fabric/src/main/java/de/sean/blockprot/fabric/nbt/PlayerSettingsHandler.java b/fabric/src/main/java/de/sean/blockprot/fabric/nbt/PlayerSettingsHandler.java new file mode 100644 index 00000000..b5d1b07f --- /dev/null +++ b/fabric/src/main/java/de/sean/blockprot/fabric/nbt/PlayerSettingsHandler.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2021 spnda + * This file is part of BlockProt . + * + * BlockProt is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * BlockProt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with BlockProt. If not, see . + */ + +package de.sean.blockprot.fabric.nbt; + +import de.sean.blockprot.fabric.ext.PlayerEntityNbtExtension; +import de.sean.blockprot.nbt.INBTHandler; +import de.sean.blockprot.nbt.IPlayerSettingsHandler; +import de.sean.blockprot.util.BlockProtUtil; +import net.minecraft.entity.player.PlayerEntity; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +/** + * A simple handler to get a player's BlockProt settings. + * + * @since 0.2.3 + */ +public final class PlayerSettingsHandler extends IPlayerSettingsHandler { + /** + * Create a new settings handler. + * + * @param player The player to get the settings for. + * @since 0.2.3 + */ + public PlayerSettingsHandler(PlayerEntity player) { + super(player); + this.container = (PlayerEntityNbtExtension) player; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean getLockOnPlace() { + // We will default to 'true'. The default value for a boolean is 'false', + // which would also be the default value for NBTCompound#getBoolean + if (!container.contains(LOCK_ON_PLACE_ATTRIBUTE)) return true; + return container.getBoolean(LOCK_ON_PLACE_ATTRIBUTE); + } + + /** + * {@inheritDoc} + */ + @Override + public void setLockOnPlace(boolean value) { + container.putBoolean(LOCK_ON_PLACE_ATTRIBUTE, value); + } + + /** + * {@inheritDoc} + */ + @Override + public @NotNull List getDefaultFriends() { + if (!container.contains(DEFAULT_FRIENDS_ATTRIBUTE)) return new ArrayList<>(); + else { + return BlockProtUtil + .parseStringList(container.getString(DEFAULT_FRIENDS_ATTRIBUTE)); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void setDefaultFriends(@NotNull List friends) { + container.putString(DEFAULT_FRIENDS_ATTRIBUTE, friends.toString()); + } + + /** + * {@inheritDoc} + */ + @Deprecated + @Override + public @NotNull List getDefaultFriendsAsPlayers() { + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public @NotNull String getName() { + return ""; + } + + /** + * {@inheritDoc} + */ + @Override + public void mergeHandler(@NotNull INBTHandler handler) { + if (!(handler instanceof final PlayerSettingsHandler otherHandler)) return; + this.setLockOnPlace(otherHandler.getLockOnPlace()); + this.container.putString(DEFAULT_FRIENDS_ATTRIBUTE, + otherHandler.container.getString(DEFAULT_FRIENDS_ATTRIBUTE)); + } +} diff --git a/fabric/src/main/java/de/sean/blockprot/fabric/screens/BlockLockScreen.java b/fabric/src/main/java/de/sean/blockprot/fabric/screens/BlockLockScreen.java new file mode 100644 index 00000000..6cb6a674 --- /dev/null +++ b/fabric/src/main/java/de/sean/blockprot/fabric/screens/BlockLockScreen.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2021 spnda + * This file is part of BlockProt . + * + * BlockProt is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * BlockProt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with BlockProt. If not, see . + */ + +package de.sean.blockprot.fabric.screens; + +import de.sean.blockprot.fabric.nbt.BlockNBTHandler; +import net.minecraft.block.BlockState; +import net.minecraft.screen.ScreenHandlerType; +import net.minecraft.server.network.ServerPlayerEntity; + +public class BlockLockScreen extends BlockProtFabricScreen { + /** + * Constructs a new simple container gui for the supplied player. + * + * @param player the player to server this gui to + */ + public BlockLockScreen(ServerPlayerEntity player) { + super(ScreenHandlerType.GENERIC_9X1, player, true); + } + + @Override + public int getRows() { + return 1; + } + + @Override + public String getDefaultScreenName() { + return "Block Lock"; + } + + public void fill(ServerPlayerEntity player, BlockState block, BlockNBTHandler handler) { + + } +} diff --git a/fabric/src/main/java/de/sean/blockprot/fabric/screens/BlockProtFabricScreen.java b/fabric/src/main/java/de/sean/blockprot/fabric/screens/BlockProtFabricScreen.java new file mode 100644 index 00000000..4de4db5f --- /dev/null +++ b/fabric/src/main/java/de/sean/blockprot/fabric/screens/BlockProtFabricScreen.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2021 spnda + * This file is part of BlockProt . + * + * BlockProt is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * BlockProt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with BlockProt. If not, see . + */ + +package de.sean.blockprot.fabric.screens; + +import de.sean.blockprot.fabric.translation.TranslationIdentifier; +import de.sean.blockprot.screens.BlockProtScreen; +import eu.pb4.sgui.api.gui.SimpleGui; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.screen.ScreenHandlerType; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.LiteralText; + +public abstract class BlockProtFabricScreen extends SimpleGui implements BlockProtScreen { + /** + * Constructs a new simple container gui for the supplied player. + * + * @param type the screen handler that the client should display + * @param player the player to server this gui to + * @param includePlayerInventorySlots if true the players inventory + */ + public BlockProtFabricScreen(ScreenHandlerType type, ServerPlayerEntity player, boolean includePlayerInventorySlots) { + super(type, player, includePlayerInventorySlots); + + this.setTitle(new LiteralText(this.getDefaultScreenName())); + } + + @Override + public void setBackButton() { + setBackButton(getSize() - 1); + } + + @Override + public void setBackButton(int index) { + setItemStack(index, Items.BLACK_STAINED_GLASS_PANE, TranslationIdentifier.SCREEN_BACK); + } + + @Override + public void setItemStack(int index, Item item) { + setItemStack(index, item, ""); + } + + @Override + public void setItemStack(int index, Item item, TranslationIdentifier identifier) { + + } + + @Override + public void setItemStack(int index, Item item, String name) { + ItemStack stack = new ItemStack(item); + stack.setCustomName(new LiteralText(name)); + setSlot(index, stack); + } +} diff --git a/fabric/src/main/java/de/sean/blockprot/fabric/translation/TranslationIdentifier.java b/fabric/src/main/java/de/sean/blockprot/fabric/translation/TranslationIdentifier.java new file mode 100644 index 00000000..d5b08af6 --- /dev/null +++ b/fabric/src/main/java/de/sean/blockprot/fabric/translation/TranslationIdentifier.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2021 spnda + * This file is part of BlockProt . + * + * BlockProt is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * BlockProt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with BlockProt. If not, see . + */ + +package de.sean.blockprot.fabric.translation; + +import net.minecraft.text.TranslatableText; +import org.jetbrains.annotations.NotNull; + +public enum TranslationIdentifier { + SCREEN_LOCK("screen.blockprot.block_lock"), + SCREEN_FRIENDS_PERMISSION_READ("screen.blockprot.friends.permission.read"), + SCREEN_FRIENDS_PERMISSION_WRITE("screen.blockprot.friends.permission.write"), + SCREEN_BACK("screen.blockprot.back"), + MESSAGES_UNLOCKED("messages.blockprot.unlocked"), + MESSAGES_LOCKED("messages.blockprot.locked"), + MESSAGES_PERMISSION_GRANTED("messages.blockprot.permission_granted"), + MESSAGES_NO_PERMISSION("messages.blockprot.no_permission"); + + private final String identifier; + + TranslationIdentifier(@NotNull final String identifier) { + this.identifier = identifier; + } + + public String getIdentifier() { + return this.identifier; + } + + public TranslatableText asTranslatableText() { + return new TranslatableText(this.identifier); + } +} diff --git a/fabric/src/main/java/de/sean/blockprot/fabric/util/PlayerUtil.java b/fabric/src/main/java/de/sean/blockprot/fabric/util/PlayerUtil.java new file mode 100644 index 00000000..f18d4c5e --- /dev/null +++ b/fabric/src/main/java/de/sean/blockprot/fabric/util/PlayerUtil.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2021 spnda + * This file is part of BlockProt . + * + * BlockProt is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * BlockProt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with BlockProt. If not, see . + */ + +package de.sean.blockprot.fabric.util; + +import net.minecraft.entity.player.PlayerEntity; +import org.jetbrains.annotations.NotNull; + +public class PlayerUtil { + public static boolean isOp(@NotNull final PlayerEntity player) { + var server = player.getServer(); + return server != null && server.getPlayerManager().isOperator(player.getGameProfile()); + } +} diff --git a/fabric/src/main/resources/assets/blockprot/icon.png b/fabric/src/main/resources/assets/blockprot/icon.png new file mode 100644 index 00000000..07c8bfcc Binary files /dev/null and b/fabric/src/main/resources/assets/blockprot/icon.png differ diff --git a/fabric/src/main/resources/assets/blockprot/lang/en_us.json b/fabric/src/main/resources/assets/blockprot/lang/en_us.json new file mode 100644 index 00000000..26bddfae --- /dev/null +++ b/fabric/src/main/resources/assets/blockprot/lang/en_us.json @@ -0,0 +1,3 @@ +{ + "screen.blockprot.block_lock": "Block Lock" +} diff --git a/fabric/src/main/resources/blockprot.accesswidener b/fabric/src/main/resources/blockprot.accesswidener new file mode 100644 index 00000000..f341b463 --- /dev/null +++ b/fabric/src/main/resources/blockprot.accesswidener @@ -0,0 +1,4 @@ +accessWidener v1 named + +accessible field net/minecraft/nbt/NbtCompound entries Ljava/util/Map; +accessible field net/minecraft/screen/GenericContainerScreenHandler inventory Lnet/minecraft/inventory/Inventory; diff --git a/fabric/src/main/resources/blockprot.mixins.json b/fabric/src/main/resources/blockprot.mixins.json new file mode 100644 index 00000000..a48322fe --- /dev/null +++ b/fabric/src/main/resources/blockprot.mixins.json @@ -0,0 +1,16 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "de.sean.blockprot.fabric.mixin", + "compatibilityLevel": "JAVA_16", + "server": [ + "MixinBlockEntity", + "MixinPlayerEntity" + ], + "injectors": { + "defaultRequire": 1 + }, + "mixins": [ + "MixinBlock" + ] +} diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json new file mode 100644 index 00000000..03a360ad --- /dev/null +++ b/fabric/src/main/resources/fabric.mod.json @@ -0,0 +1,38 @@ +{ + "schemaVersion": 1, + "id": "blockprot", + "version": "${version}", + "name": "BlockProt", + "description": "A simple block protection plugin", + "authors": [ + "spnda" + ], + "contact": { + "homepage": "https://github.com/spnda/BukkitPlugins", + "sources": "https://github.com/spnda/BukkitPlugins" + }, + "license": "GPLv3", + "icon": "assets/blockprot/icon.png", + "environment": "server", + "entrypoints": { + "server": [ + "de.sean.blockprot.fabric.BlockProt" + ] + }, + "mixins": [ + "blockprot.mixins.json" + ], + "accessWidener": "blockprot.accesswidener", + "depends": { + "fabricloader": ">=0.11.3", + "fabric": "*", + "minecraft": "1.17.x", + "java": ">=16", + "sgui": "*" + }, + "custom": { + "modmenu": { + + } + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 958fe477..a6f1cf2b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,8 +1,17 @@ +pluginManagement { + repositories { + gradlePluginPortal() + maven("https://maven.fabricmc.net/") { + name = "Fabric" + } + } +} + rootProject.name = "blockprot" include("common") -val subprojects = listOf("spigot") +val subprojects = listOf("spigot", "fabric") subprojects.forEach { include(it) project(":$it").name = "${rootProject.name}-$it" diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/BlockProt.java b/spigot/src/main/java/de/sean/blockprot/bukkit/BlockProt.java index 4a52a292..63290d4e 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/BlockProt.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/BlockProt.java @@ -24,6 +24,7 @@ import de.sean.blockprot.bukkit.integrations.TownyIntegration; import de.sean.blockprot.bukkit.listeners.*; import de.sean.blockprot.bukkit.tasks.UpdateChecker; +import de.sean.blockprot.bukkit.translation.Translator; import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; import org.bukkit.command.TabExecutor; @@ -211,7 +212,7 @@ private void loadTranslations(String fileName) { * * @param folder The name of the folder where the file is located. * @param name The name of the resource. - * @param replace Whether or not to replace the file if it already exists. + * @param replace Whether to replace the file if it already exists. * @return The YamlConfiguration. * @since 0.4.7 */ diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/BlockProtAPI.java b/spigot/src/main/java/de/sean/blockprot/bukkit/BlockProtAPI.java index c4b8da30..b298d93f 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/BlockProtAPI.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/BlockProtAPI.java @@ -20,7 +20,7 @@ import de.sean.blockprot.bukkit.events.BlockAccessEditMenuEvent; import de.sean.blockprot.bukkit.integrations.PluginIntegration; -import de.sean.blockprot.bukkit.inventories.BlockLockInventory; +import de.sean.blockprot.bukkit.inventories.BlockLockScreen; import de.sean.blockprot.bukkit.inventories.InventoryState; import de.sean.blockprot.bukkit.nbt.BlockNBTHandler; import de.sean.blockprot.bukkit.nbt.PlayerSettingsHandler; @@ -157,7 +157,7 @@ public Inventory getLockInventoryForBlock(@NotNull final Block block, @NotNull f state.friendSearchState = InventoryState.FriendSearchState.FRIEND_SEARCH; InventoryState.set(player.getUniqueId(), state); - return new BlockLockInventory().fill(player, block.getType(), handler); + return new BlockLockScreen().fill(player, block.getType(), handler); } } } diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/commands/BlockProtCommand.java b/spigot/src/main/java/de/sean/blockprot/bukkit/commands/BlockProtCommand.java index 170d5f5f..686bba5f 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/commands/BlockProtCommand.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/commands/BlockProtCommand.java @@ -20,7 +20,7 @@ import de.sean.blockprot.bukkit.BlockProt; import de.sean.blockprot.bukkit.inventories.InventoryState; -import de.sean.blockprot.bukkit.inventories.UserSettingsInventory; +import de.sean.blockprot.bukkit.inventories.UserSettingsScreen; import de.sean.blockprot.bukkit.tasks.UpdateChecker; import org.bukkit.Bukkit; import org.bukkit.command.Command; @@ -28,7 +28,6 @@ import org.bukkit.command.TabExecutor; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Collections; @@ -61,7 +60,7 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command InventoryState state = new InventoryState(null); state.friendSearchState = InventoryState.FriendSearchState.DEFAULT_FRIEND_SEARCH; InventoryState.set(player.getUniqueId(), state); - player.openInventory(new UserSettingsInventory().fill(player)); + player.openInventory(new UserSettingsScreen().fill(player)); return true; } else { return false; @@ -72,7 +71,7 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command return false; } - @Nullable + @NotNull @Override public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) { if (args.length <= 1) { diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/config/BlockProtConfig.java b/spigot/src/main/java/de/sean/blockprot/bukkit/config/BlockProtConfig.java index 7af86c3a..0a0b77e2 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/config/BlockProtConfig.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/config/BlockProtConfig.java @@ -21,9 +21,11 @@ import org.bukkit.Bukkit; import org.bukkit.configuration.file.FileConfiguration; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; /** * Represents a basic YAML configuration file with some diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/BlockInfoInventory.java b/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/BlockInfoScreen.java similarity index 93% rename from spigot/src/main/java/de/sean/blockprot/bukkit/inventories/BlockInfoInventory.java rename to spigot/src/main/java/de/sean/blockprot/bukkit/inventories/BlockInfoScreen.java index 16836672..5e305c22 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/BlockInfoInventory.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/BlockInfoScreen.java @@ -19,10 +19,10 @@ package de.sean.blockprot.bukkit.inventories; import de.sean.blockprot.bukkit.BlockProt; -import de.sean.blockprot.bukkit.TranslationKey; -import de.sean.blockprot.bukkit.Translator; import de.sean.blockprot.bukkit.nbt.BlockNBTHandler; import de.sean.blockprot.bukkit.nbt.FriendHandler; +import de.sean.blockprot.bukkit.translation.TranslationKey; +import de.sean.blockprot.bukkit.translation.Translator; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.OfflinePlayer; @@ -36,12 +36,12 @@ import java.util.List; import java.util.UUID; -public class BlockInfoInventory extends BlockProtInventory { - private final int maxSkulls = getSize() - InventoryConstants.singleLine; +public class BlockInfoScreen extends BlockProtBukkitScreen { + private final int maxSkulls = getRows() - InventoryConstants.singleLine; @Override - int getSize() { - return 9 * 6; + public int getRows() { + return 6; } @NotNull @@ -64,7 +64,7 @@ public void onClick(@NotNull InventoryClickEvent event, @NotNull InventoryState player, handler == null ? null - : new BlockLockInventory().fill(player, state.getBlock().getType(), handler) + : new BlockLockScreen().fill(player, state.getBlock().getType(), handler) ); } break; diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/BlockLockInventory.java b/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/BlockLockScreen.java similarity index 94% rename from spigot/src/main/java/de/sean/blockprot/bukkit/inventories/BlockLockInventory.java rename to spigot/src/main/java/de/sean/blockprot/bukkit/inventories/BlockLockScreen.java index fdda8bf8..046c5c7d 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/BlockLockInventory.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/BlockLockScreen.java @@ -19,10 +19,10 @@ package de.sean.blockprot.bukkit.inventories; import de.sean.blockprot.bukkit.BlockProt; -import de.sean.blockprot.bukkit.TranslationKey; -import de.sean.blockprot.bukkit.Translator; import de.sean.blockprot.bukkit.events.BlockAccessEditMenuEvent; import de.sean.blockprot.bukkit.nbt.BlockNBTHandler; +import de.sean.blockprot.bukkit.translation.TranslationKey; +import de.sean.blockprot.bukkit.translation.Translator; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Player; @@ -32,11 +32,11 @@ import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; -public class BlockLockInventory extends BlockProtInventory { +public class BlockLockScreen extends BlockProtBukkitScreen { private boolean redstone = false; @Override - int getSize() { + public int getRows() { return InventoryConstants.singleLine; } @@ -71,7 +71,7 @@ public void onClick(@NotNull InventoryClickEvent event, @NotNull InventoryState } else if (item.getType() == Material.PLAYER_HEAD) { closeAndOpen( player, - new FriendManageInventory().fill(player) + new FriendManageScreen().fill(player) ); } else if (item.getType() == Material.OAK_SIGN) { BlockNBTHandler handler = getNbtHandlerOrNull(block); @@ -79,7 +79,7 @@ public void onClick(@NotNull InventoryClickEvent event, @NotNull InventoryState player, handler == null ? null - : new BlockInfoInventory().fill(player, handler) + : new BlockInfoScreen().fill(player, handler) ); } else { closeAndOpen( diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/BlockProtInventory.java b/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/BlockProtBukkitScreen.java similarity index 95% rename from spigot/src/main/java/de/sean/blockprot/bukkit/inventories/BlockProtInventory.java rename to spigot/src/main/java/de/sean/blockprot/bukkit/inventories/BlockProtBukkitScreen.java index ecbf49b0..1e8a9afa 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/BlockProtInventory.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/BlockProtBukkitScreen.java @@ -18,13 +18,14 @@ package de.sean.blockprot.bukkit.inventories; -import de.sean.blockprot.bukkit.TranslationKey; -import de.sean.blockprot.bukkit.Translator; import de.sean.blockprot.bukkit.nbt.BlockNBTHandler; import de.sean.blockprot.bukkit.nbt.FriendHandler; import de.sean.blockprot.bukkit.nbt.PlayerSettingsHandler; import de.sean.blockprot.nbt.FriendModifyAction; import de.sean.blockprot.nbt.LockReturnValue; +import de.sean.blockprot.bukkit.translation.TranslationKey; +import de.sean.blockprot.bukkit.translation.Translator; +import de.sean.blockprot.screens.BlockProtScreen; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.OfflinePlayer; @@ -54,18 +55,18 @@ * * @since 0.2.2 */ -public abstract class BlockProtInventory implements InventoryHolder { +public abstract class BlockProtBukkitScreen implements InventoryHolder, BlockProtScreen { /** * @since 0.2.2 */ protected final Inventory inventory; /** - * Creates a new inventory using {@link BlockProtInventory#createInventory()}. + * Creates a new inventory using {@link BlockProtBukkitScreen#createInventory()}. * * @since 0.2.2 */ - public BlockProtInventory() { + public BlockProtBukkitScreen() { inventory = createInventory(); } @@ -81,15 +82,6 @@ public final Inventory getInventory() { return inventory; } - /** - * Get the size of this inventory, which should be a multiple of 9 with a maximum value of 6 * - * 9. - * - * @return The size of this inventory. - * @since 0.2.2 - */ - abstract int getSize(); - /** * Gets the translated name of this inventory, or an empty String if not translatable, by * the default TranslationKey for this inventory holder. @@ -107,8 +99,9 @@ public final Inventory getInventory() { * found. * @since 0.2.2 */ + @Override @NotNull - public final String getDefaultInventoryName() { + public final String getDefaultScreenName() { final String inventoryName = getTranslatedInventoryName(); return inventoryName.isEmpty() ? this.getClass().getSimpleName() : inventoryName; } @@ -132,7 +125,7 @@ public final String getDefaultInventoryName() { public abstract void onClose(@NotNull final InventoryCloseEvent event, @NotNull final InventoryState state); /** - * Create this current inventory. If {@link BlockProtInventory#getTranslatedInventoryName()} + * Create this current inventory. If {@link BlockProtBukkitScreen#getTranslatedInventoryName()} * returns an empty String, this class's simple name will be used. * * @return The Bukkit Inventory. @@ -140,7 +133,7 @@ public final String getDefaultInventoryName() { */ @NotNull protected final Inventory createInventory() { - return Bukkit.createInventory(this, getSize(), getDefaultInventoryName()); + return Bukkit.createInventory(this, getRows(), getDefaultScreenName()); } /** @@ -282,6 +275,7 @@ protected List filterList( * * @since 0.2.3 */ + @Override public void setBackButton() { setBackButton(inventory.getSize() - 1); } @@ -292,10 +286,17 @@ public void setBackButton() { * @param index The index of the back button inside this inventory. * @since 0.2.3 */ + @Override public void setBackButton(int index) { setItemStack(index, Material.BLACK_STAINED_GLASS_PANE, TranslationKey.INVENTORIES__BACK); } + @Override + @Deprecated + public void setItemStack(int index, Material material) { + setItemStack(index, material, ""); + } + /** * Sets a ItemStack with the type [material] and the name translated by [key] at [index]. * @@ -304,6 +305,7 @@ public void setBackButton(int index) { * @param key The translation key to use to get the translated name for this item. * @since 0.2.3 */ + @Override public void setItemStack(int index, Material material, TranslationKey key) { setItemStack(index, material, Translator.get(key)); } @@ -331,6 +333,7 @@ public void setItemStack(int index, Material material, TranslationKey key, List< * @param text The text or name of the item. * @since 0.4.0 */ + @Override public void setItemStack(int index, Material material, String text) { setItemStack(index, material, text, Collections.emptyList()); } diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendDetailInventory.java b/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendDetailScreen.java similarity index 93% rename from spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendDetailInventory.java rename to spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendDetailScreen.java index 8c230a0c..b6e8c07e 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendDetailInventory.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendDetailScreen.java @@ -18,12 +18,12 @@ package de.sean.blockprot.bukkit.inventories; -import de.sean.blockprot.nbt.FriendModifyAction; -import de.sean.blockprot.bukkit.TranslationKey; -import de.sean.blockprot.bukkit.Translator; -import de.sean.blockprot.bukkit.nbt.BlockAccessFlag; import de.sean.blockprot.bukkit.nbt.BlockNBTHandler; import de.sean.blockprot.bukkit.nbt.FriendHandler; +import de.sean.blockprot.bukkit.translation.TranslationKey; +import de.sean.blockprot.bukkit.translation.Translator; +import de.sean.blockprot.bukkit.nbt.BlockAccessFlag; +import de.sean.blockprot.nbt.FriendModifyAction; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.OfflinePlayer; @@ -40,7 +40,7 @@ /** * The detail inventory for managing a single friend and their permission. */ -public final class FriendDetailInventory extends BlockProtInventory { +public final class FriendDetailScreen extends BlockProtBukkitScreen { @NotNull private static final List> accessFlagCombinations = Arrays.asList( @@ -54,7 +54,7 @@ public final class FriendDetailInventory extends BlockProtInventory { private FriendHandler playerHandler = null; @Override - public int getSize() { + public int getRows() { return InventoryConstants.singleLine; } @@ -72,7 +72,7 @@ public void onClick(@NotNull InventoryClickEvent event, @NotNull InventoryState switch (item.getType()) { case BLACK_STAINED_GLASS_PANE: { - closeAndOpen(player, new FriendManageInventory().fill(player)); + closeAndOpen(player, new FriendManageScreen().fill(player)); break; } case RED_STAINED_GLASS_PANE: { @@ -81,7 +81,7 @@ public void onClick(@NotNull InventoryClickEvent event, @NotNull InventoryState modifyFriendsForAction(player, friend, FriendModifyAction.REMOVE_FRIEND); // We remove the friend, so the player does not exist anymore either. this.playerHandler = null; - closeAndOpen(player, new FriendManageInventory().fill(player)); + closeAndOpen(player, new FriendManageScreen().fill(player)); break; } case ENDER_EYE: { diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendManageInventory.java b/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendManageScreen.java similarity index 92% rename from spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendManageInventory.java rename to spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendManageScreen.java index a593b1b0..a21365b4 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendManageInventory.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendManageScreen.java @@ -19,12 +19,12 @@ package de.sean.blockprot.bukkit.inventories; import de.sean.blockprot.bukkit.BlockProt; -import de.sean.blockprot.bukkit.TranslationKey; -import de.sean.blockprot.bukkit.Translator; import de.sean.blockprot.bukkit.integrations.PluginIntegration; import de.sean.blockprot.bukkit.inventories.InventoryState.FriendSearchState; import de.sean.blockprot.bukkit.nbt.BlockNBTHandler; import de.sean.blockprot.bukkit.nbt.PlayerSettingsHandler; +import de.sean.blockprot.bukkit.translation.TranslationKey; +import de.sean.blockprot.bukkit.translation.Translator; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.OfflinePlayer; @@ -42,12 +42,12 @@ import java.util.UUID; import java.util.stream.Collectors; -public final class FriendManageInventory extends BlockProtInventory { +public final class FriendManageScreen extends BlockProtBukkitScreen { private int maxSkulls = getSize() - 5; @Override - public int getSize() { - return 9 * 6; // 6 Lines of inventory go brr + public int getRows() { + return 6; // 6 Lines of inventory go brr } @NotNull @@ -57,8 +57,8 @@ public String getTranslatedInventoryName() { } /** - * Exits this inventory depending on {@code state}'s {@link FriendSearchState} back to the {@link BlockLockInventory} - * or the {@link UserSettingsInventory} respectively. + * Exits this inventory depending on {@code state}'s {@link FriendSearchState} back to the {@link BlockLockScreen} + * or the {@link UserSettingsScreen} respectively. * * @param player The player to open/close the inventory for. * @param state The {@code player}'s state. @@ -72,7 +72,7 @@ public void exitModifyInventory(@NotNull final Player player, @NotNull final Inv if (handler == null) { newInventory = null; } else { - newInventory = new BlockLockInventory() + newInventory = new BlockLockScreen() .fill( player, state.getBlock().getState().getType(), @@ -81,7 +81,7 @@ public void exitModifyInventory(@NotNull final Player player, @NotNull final Inv break; } case DEFAULT_FRIEND_SEARCH: - newInventory = new UserSettingsInventory().fill(player); + newInventory = new UserSettingsScreen().fill(player); break; default: return; @@ -126,7 +126,7 @@ public void onClick(@NotNull InventoryClickEvent event, @NotNull InventoryState int index = findItemIndex(item); if (index < 0 || index >= state.friendResultCache.size()) break; state.currentFriend = state.friendResultCache.get(index); - final Inventory inv = new FriendDetailInventory().fill(player); + final Inventory inv = new FriendDetailScreen().fill(player); closeAndOpen(player, inv); break; } @@ -135,7 +135,7 @@ public void onClick(@NotNull InventoryClickEvent event, @NotNull InventoryState break; } case BOOK: - closeAndOpen(player, new FriendSearchHistoryInventory().fill(player)); + closeAndOpen(player, new FriendSearchHistoryScreen().fill(player)); break; default: { // Unexpected, exit the inventory. diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendSearchHistoryInventory.java b/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendSearchHistoryScreen.java similarity index 90% rename from spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendSearchHistoryInventory.java rename to spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendSearchHistoryScreen.java index de54d053..21ca9592 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendSearchHistoryInventory.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendSearchHistoryScreen.java @@ -19,8 +19,8 @@ package de.sean.blockprot.bukkit.inventories; import de.sean.blockprot.bukkit.BlockProt; -import de.sean.blockprot.bukkit.TranslationKey; -import de.sean.blockprot.bukkit.Translator; +import de.sean.blockprot.bukkit.translation.TranslationKey; +import de.sean.blockprot.bukkit.translation.Translator; import de.sean.blockprot.bukkit.nbt.PlayerSettingsHandler; import de.sean.blockprot.nbt.FriendModifyAction; import org.bukkit.Bukkit; @@ -41,12 +41,12 @@ * searched for. This can be used to easily add a player that they * had just searched for again. */ -public class FriendSearchHistoryInventory extends BlockProtInventory { +public class FriendSearchHistoryScreen extends BlockProtBukkitScreen { private final int maxSkulls = getSize() - 2; @Override - int getSize() { - return InventoryConstants.tripleLine; + public int getRows() { + return 3; } @Override @@ -61,7 +61,7 @@ public void onClick(@NotNull InventoryClickEvent event, @NotNull InventoryState if (item == null) return; switch (item.getType()) { case BLACK_STAINED_GLASS_PANE: { - closeAndOpen(player, new FriendManageInventory().fill(player)); + closeAndOpen(player, new FriendManageScreen().fill(player)); break; } case PLAYER_HEAD: @@ -70,7 +70,7 @@ public void onClick(@NotNull InventoryClickEvent event, @NotNull InventoryState if (index >= 0 && index < state.friendResultCache.size()) { OfflinePlayer friend = state.friendResultCache.get(index); modifyFriendsForAction(player, friend, FriendModifyAction.ADD_FRIEND); - closeAndOpen(player, new FriendManageInventory().fill(player)); + closeAndOpen(player, new FriendManageScreen().fill(player)); } break; } diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendSearchInventory.java b/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendSearchInventory.java index 2ce82be5..0dff00e4 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendSearchInventory.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendSearchInventory.java @@ -19,8 +19,8 @@ package de.sean.blockprot.bukkit.inventories; import de.sean.blockprot.bukkit.BlockProt; -import de.sean.blockprot.bukkit.TranslationKey; -import de.sean.blockprot.bukkit.Translator; +import de.sean.blockprot.bukkit.translation.TranslationKey; +import de.sean.blockprot.bukkit.translation.Translator; import net.wesjd.anvilgui.AnvilGUI; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; @@ -41,7 +41,7 @@ public static void openAnvilInventory(@NotNull final Player requestingPlayer) { } private static AnvilGUI.Response onCompleteCallback(@NotNull final Player player, @NotNull final String searchQuery) { - Inventory inventory = new FriendSearchResultInventory().fill(player, searchQuery); + Inventory inventory = new FriendSearchResultScreen().fill(player, searchQuery); if (inventory == null) return AnvilGUI.Response.close(); return AnvilGUI.Response.openInventory(inventory); } diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendSearchResultInventory.java b/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendSearchResultScreen.java similarity index 95% rename from spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendSearchResultInventory.java rename to spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendSearchResultScreen.java index 8e8aa543..615d7cad 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendSearchResultInventory.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendSearchResultScreen.java @@ -20,12 +20,13 @@ import de.sean.blockprot.nbt.FriendModifyAction; import de.sean.blockprot.bukkit.BlockProt; -import de.sean.blockprot.bukkit.TranslationKey; -import de.sean.blockprot.bukkit.Translator; import de.sean.blockprot.bukkit.integrations.PluginIntegration; import de.sean.blockprot.bukkit.nbt.BlockNBTHandler; import de.sean.blockprot.bukkit.nbt.FriendHandler; import de.sean.blockprot.bukkit.nbt.PlayerSettingsHandler; +import de.sean.blockprot.bukkit.translation.TranslationKey; +import de.sean.blockprot.bukkit.translation.Translator; +import de.sean.blockprot.nbt.FriendModifyAction; import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; import org.bukkit.Material; @@ -44,9 +45,9 @@ import java.util.List; import java.util.stream.Collectors; -public class FriendSearchResultInventory extends BlockProtInventory { +public class FriendSearchResultScreen extends BlockProtBukkitScreen { @Override - int getSize() { + public int getRows() { return InventoryConstants.tripleLine; } @@ -69,7 +70,7 @@ public void onClick(@NotNull InventoryClickEvent event, @NotNull InventoryState // go right back to the FriendAddInventory. closeAndOpen( player, - new FriendManageInventory().fill(player) + new FriendManageScreen().fill(player) ); break; case PLAYER_HEAD: @@ -78,7 +79,7 @@ public void onClick(@NotNull InventoryClickEvent event, @NotNull InventoryState if (index >= 0 && index < state.friendResultCache.size()) { OfflinePlayer friend = state.friendResultCache.get(index); modifyFriendsForAction(player, friend, FriendModifyAction.ADD_FRIEND); - closeAndOpen(player, new FriendManageInventory().fill(player)); + closeAndOpen(player, new FriendManageScreen().fill(player)); // Update the search history PlayerSettingsHandler settingsHandler = new PlayerSettingsHandler(player); diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/InventoryState.java b/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/InventoryState.java index 1dcddf93..a225be3b 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/InventoryState.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/InventoryState.java @@ -67,14 +67,14 @@ public final class InventoryState { public FriendSearchState friendSearchState = FriendSearchState.FRIEND_SEARCH; /** - * The current index of the {@link BlockProtInventory} page. + * The current index of the {@link BlockProtBukkitScreen} page. * * @since 0.4.7 */ public int friendPage = 0; /** - * The friend we currently want to modify with {@link FriendDetailInventory}. + * The friend we currently want to modify with {@link FriendDetailScreen}. * * @since 0.4.7 */ diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/UserSettingsInventory.java b/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/UserSettingsScreen.java similarity index 92% rename from spigot/src/main/java/de/sean/blockprot/bukkit/inventories/UserSettingsInventory.java rename to spigot/src/main/java/de/sean/blockprot/bukkit/inventories/UserSettingsScreen.java index afb82740..edea538f 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/UserSettingsInventory.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/UserSettingsScreen.java @@ -18,9 +18,9 @@ package de.sean.blockprot.bukkit.inventories; -import de.sean.blockprot.bukkit.TranslationKey; -import de.sean.blockprot.bukkit.Translator; import de.sean.blockprot.bukkit.nbt.PlayerSettingsHandler; +import de.sean.blockprot.bukkit.translation.TranslationKey; +import de.sean.blockprot.bukkit.translation.Translator; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.InventoryClickEvent; @@ -29,9 +29,9 @@ import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; -public class UserSettingsInventory extends BlockProtInventory { +public class UserSettingsScreen extends BlockProtBukkitScreen { @Override - int getSize() { + public int getRows() { return InventoryConstants.singleLine; } @@ -62,7 +62,7 @@ public void onClick(@NotNull InventoryClickEvent event, @NotNull InventoryState break; case PLAYER_HEAD: state.friendSearchState = InventoryState.FriendSearchState.DEFAULT_FRIEND_SEARCH; - closeAndOpen(player, new FriendManageInventory().fill(player)); + closeAndOpen(player, new FriendManageScreen().fill(player)); break; default: closeAndOpen(player, null); // This also includes Material.BLACK_STAINED_GLASS_PANE diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/HopperEventListener.java b/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/HopperEventListener.java index 9549e38d..96614fe0 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/HopperEventListener.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/HopperEventListener.java @@ -20,7 +20,9 @@ import de.sean.blockprot.bukkit.BlockProt; import de.sean.blockprot.bukkit.nbt.BlockNBTHandler; -import org.bukkit.block.*; +import org.bukkit.block.Block; +import org.bukkit.block.Container; +import org.bukkit.block.DoubleChest; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.inventory.InventoryMoveItemEvent; diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/InteractEventListener.java b/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/InteractEventListener.java index af7ed9b8..8ce7dc84 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/InteractEventListener.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/InteractEventListener.java @@ -20,11 +20,10 @@ import de.sean.blockprot.bukkit.BlockProt; import de.sean.blockprot.bukkit.BlockProtAPI; -import de.sean.blockprot.bukkit.TranslationKey; -import de.sean.blockprot.bukkit.Translator; import de.sean.blockprot.bukkit.events.BlockAccessEvent; import de.sean.blockprot.bukkit.nbt.BlockNBTHandler; -import de.sean.blockprot.bukkit.nbt.NBTHandler; +import de.sean.blockprot.bukkit.translation.TranslationKey; +import de.sean.blockprot.bukkit.translation.Translator; import net.md_5.bungee.api.ChatMessageType; import net.md_5.bungee.api.chat.TextComponent; import org.bukkit.Bukkit; @@ -51,12 +50,12 @@ public void playerInteract(PlayerInteractEvent event) { sendMessage(player, Translator.get(TranslationKey.MESSAGES__NO_PERMISSION)); } else { BlockNBTHandler handler = new BlockNBTHandler(event.getClickedBlock()); - if (!(handler.canAccess(player.getUniqueId().toString()) || player.hasPermission(NBTHandler.PERMISSION_BYPASS))) { + if (!(handler.canAccess(player.getUniqueId().toString()) || player.hasPermission(BlockNBTHandler.PERMISSION_BYPASS))) { event.setCancelled(true); sendMessage(player, Translator.get(TranslationKey.MESSAGES__NO_PERMISSION)); } } - } else if (event.getAction() == Action.RIGHT_CLICK_BLOCK && player.isSneaking() && player.hasPermission(NBTHandler.PERMISSION_LOCK)) { + } else if (event.getAction() == Action.RIGHT_CLICK_BLOCK && player.isSneaking() && player.hasPermission(BlockNBTHandler.PERMISSION_LOCK)) { if (event.hasItem()) return; // Only enter the menu with an empty hand. event.setCancelled(true); diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/InventoryEventListener.java b/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/InventoryEventListener.java index a1a450ca..e4ce724f 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/InventoryEventListener.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/listeners/InventoryEventListener.java @@ -19,7 +19,8 @@ package de.sean.blockprot.bukkit.listeners; import de.sean.blockprot.bukkit.BlockProt; -import de.sean.blockprot.bukkit.inventories.*; +import de.sean.blockprot.bukkit.inventories.BlockProtBukkitScreen; +import de.sean.blockprot.bukkit.inventories.InventoryState; import de.sean.blockprot.bukkit.nbt.BlockNBTHandler; import de.sean.blockprot.bukkit.nbt.FriendHandler; import org.bukkit.entity.Player; @@ -42,8 +43,8 @@ public void onInventoryClick(@NotNull InventoryClickEvent event) { // We have some sort of inventory state, so we'll // assume the player is currently in some of our inventories. InventoryHolder holder = event.getInventory().getHolder(); - if (holder instanceof BlockProtInventory) { - ((BlockProtInventory) holder).onClick(event, state); + if (holder instanceof BlockProtBukkitScreen) { + ((BlockProtBukkitScreen) holder).onClick(event, state); } } else { // No state, let's check if they're in some block inventory. @@ -83,8 +84,8 @@ public void onInventoryClose(@NotNull InventoryCloseEvent event) { if (state == null) return; InventoryHolder holder = event.getInventory().getHolder(); - if (holder instanceof BlockProtInventory) { - ((BlockProtInventory) holder).onClose(event, state); + if (holder instanceof BlockProtBukkitScreen) { + ((BlockProtBukkitScreen) holder).onClose(event, state); } } } diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/nbt/BlockAccessFlag.java b/spigot/src/main/java/de/sean/blockprot/bukkit/nbt/BlockAccessFlag.java index 49e07046..ff08a01c 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/nbt/BlockAccessFlag.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/nbt/BlockAccessFlag.java @@ -18,9 +18,9 @@ package de.sean.blockprot.bukkit.nbt; -import de.sean.blockprot.bukkit.TranslationKey; -import de.sean.blockprot.bukkit.Translator; -import org.bukkit.ChatColor; + +import de.sean.blockprot.bukkit.translation.TranslationKey; +import de.sean.blockprot.bukkit.translation.Translator; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -131,8 +131,8 @@ public static List accumulateAccessFlagLore(@NotNull final EnumSet { - static final String OWNER_ATTRIBUTE = "splugin_owner"; +public final class BlockNBTHandler extends IBlockNBTHandler { + public static final String PERMISSION_LOCK = "blockprot.lock"; - static final String OLD_LOCK_ATTRIBUTE = "splugin_lock"; + public static final String PERMISSION_INFO = "blockprot.info"; - static final String LOCK_ATTRIBUTE = "blockprot_friends"; + public static final String PERMISSION_ADMIN = "blockprot.admin"; - static final String REDSTONE_ATTRIBUTE = "splugin_lock_redstone"; + public static final String PERMISSION_BYPASS = "blockprot.bypass"; private static final boolean DEFAULT_REDSTONE = true; @@ -96,6 +94,7 @@ public BlockNBTHandler(@NotNull final Block block) throws RuntimeException { * @return The owner as a UUID-String read from the container, or an empty String. * @since 0.2.3 */ + @Override @NotNull public String getOwner() { if (!container.hasKey(OWNER_ATTRIBUTE)) return ""; @@ -103,12 +102,9 @@ public String getOwner() { } /** - * Set the current owner of this block. - * - * @param owner The new owner for this block. Should - * be a valid UUID. - * @since 0.2.3 + * {@inheritDoc} */ + @Override public void setOwner(@NotNull final String owner) { container.setString(OWNER_ATTRIBUTE, owner); } @@ -130,12 +126,9 @@ private void remapAccess() { } /** - * Gets a {@link Stream} of {@link FriendHandler} for this block. - * - * @return A stream of friend handlers for all NBT compounds under - * the friend key. - * @since 0.3.0 + * {@inheritDoc} */ + @Override @NotNull public Stream getFriendsStream() { remapAccess(); @@ -149,78 +142,42 @@ public Stream getFriendsStream() { } /** - * Gets a {@link List} of friends for this block. - * - * @return A list of {@link FriendHandler} to read - * additional data for each friend. - * @since 0.3.0 - */ - @NotNull - public List getFriends() { - return getFriendsStream().collect(Collectors.toList()); - } - - /** - * Set a new list of FriendHandler for the friends list. - * - * @param access The new list of friends to use. - * @since 0.3.0 + * {@inheritDoc} */ + @Override public void setFriends(@NotNull final List access) { container.removeKey(LOCK_ATTRIBUTE); if (!access.isEmpty()) { NBTCompound compound = container.addCompound(LOCK_ATTRIBUTE); - for (FriendHandler handler : access) { + for (IFriendHandler handler : access) { NBTCompound newCompound = compound.addCompound(handler.getName()); - newCompound.mergeCompound(handler.container); + newCompound.mergeCompound((NBTCompound) handler.getContainer()); } } } /** - * Filters the results of {@link #getFriends()} for any entry which - * id qualifies for {@link String#equals(Object)}. - * - * @param id The String ID to check for. Usually a UUID as a String as {@link UUID#toString()}. - * @return The first {@link FriendHandler} found, or none. - * @since 0.3.0 - */ - @NotNull - public Optional getFriend(@NotNull final String id) { - return getFriendsStream() - .filter((f) -> f.getName().equals(id)) - .findFirst(); - } - - /** - * Adds a new friend to the NBT. - * - * @param friend The friend to add. - * @since 0.3.0 + * {@inheritDoc} */ + @Override public void addFriend(@NotNull final String friend) { NBTCompound compound = container.getOrCreateCompound(LOCK_ATTRIBUTE); compound.addCompound(friend).setString("id", friend); } /** - * Removes a friend from the NBT. - * - * @param friend The friend to remove. - * @since 0.3.0 + * {@inheritDoc} */ + @Override public void removeFriend(@NotNull final String friend) { NBTCompound compound = container.getOrCreateCompound(LOCK_ATTRIBUTE); compound.removeKey(friend); } /** - * If true, redstone should be allowed for this block and should not be blocked. - * If redstone has not been set for this block yet, the default value is true - * - * @return Whether redstone should be allowed or not. - * @since 0.2.3 + * {@inheritDoc} */ + @Override public boolean getRedstone() { // We will default to 'true'. The default value for a boolean is 'false', // which would also be the default value for NBTCompound#getBoolean @@ -232,59 +189,13 @@ public boolean getRedstone() { } /** - * Set the new value for redstone. See {@link #getRedstone()} for more - * details on the values. - * - * @param redstone The boolean value to set. - * @since 0.2.3 + * {@inheritDoc} */ + @Override public void setRedstone(final boolean redstone) { container.setBoolean(REDSTONE_ATTRIBUTE, redstone); } - /** - * Whether or not this block is protected. This is evaluated by checking - * if an owner exists and if any friends have been added to the block. - * - * @return True, if this block is not protected and there is no owner. - * @since 0.2.3 - */ - public boolean isNotProtected() { - return getOwner().isEmpty() && getFriends().isEmpty(); - } - - /** - * @return True, if this block is protected. - * @see #isNotProtected() - * @since 0.2.3 - */ - public boolean isProtected() { - return !isNotProtected(); - } - - /** - * Checks whether or not given {@code player} is the owner of this block. - * - * @param player A String representing a players UUID. - * @return Whether or not {@code player} is the owner of this block. - * @since 0.2.3 - */ - public boolean isOwner(@NotNull final String player) { - return getOwner().equals(player); - } - - /** - * Checks whether or not given {@code player} can access this block. - * - * @param player The player to check for. - * @return True, if {@code player} can access this block. - * @since 0.2.3 - */ - public boolean canAccess(@NotNull final String player) { - Optional friend = getFriend(player); - return !isProtected() || (getOwner().equals(player) || (friend.isPresent() && friend.get().canRead())); - } - /** * Locks this block for given {@code player} as the owner. * @@ -303,13 +214,9 @@ public LockReturnValue lockBlock(@NotNull final Player player, @Nullable final N } /** - * Locks this block for given {@code player} as the owner. - * - * @param player The player to set as an owner. - * @return A {@link LockReturnValue} whether the block was successfully locked, - * else there might have been issues with permissions. - * @since 0.4.6 + * {@inheritDoc} */ + @Override @NotNull public LockReturnValue lockBlock(@NotNull final Player player) { String owner = getOwner(); @@ -349,17 +256,10 @@ public LockReturnValue lockRedstoneForBlock(@NotNull final String player, @Nulla } /** - * Locks redstone for this block. - * - * @param player The player requesting this command, should be the owner. - * @param value The value we want to set it to. If null, we just flip - * the current value. - * @return A {@link LockReturnValue} whether or not the redstone was switched - * successfully. - * @since 0.4.6 + * {@inheritDoc} + * @return */ - @NotNull - public LockReturnValue lockRedstoneForBlock(@NotNull final String player, @Nullable final Boolean value) { + public @NotNull LockReturnValue lockRedstoneForBlock(@NotNull final String player, @Nullable final Boolean value) { if (isOwner(player)) { boolean redstone = value == null ? !getRedstone() : value; setRedstone(redstone); @@ -369,20 +269,6 @@ public LockReturnValue lockRedstoneForBlock(@NotNull final String player, @Nulla return new LockReturnValue(false); } - /** - * Checks whether or not {@code friends} contains {@code friend}. - * - * @param friends A list of all friends we want to filter. - * @param friend The UUID of a player we want to check for. - * @return True, if the list does contain that friend. - * @since 0.3.0 - */ - private boolean containsFriend(@NotNull final List friends, @NotNull final String friend) { - return friends - .stream() - .anyMatch((f) -> f.getName().equals(friend)); - } - /** * @param player The player requesting this command, should be the owner. * @param friend The friend do to {@code action} with. @@ -402,14 +288,7 @@ public LockReturnValue modifyFriends(@NotNull final String player, @NotNull fina } /** - * Modifies the friends of this block for given {@code action}. - * - * @param player The player requesting this command, should be the owner. - * @param friend The friend do to {@code action} with. - * @param action The action we should perform with {@code friend} on this block. - * @return A {@link LockReturnValue} whether or not the friends were modified - * successfully. - * @since 0.4.6 + * {@inheritDoc} */ @NotNull public LockReturnValue modifyFriends(@NotNull final String player, @NotNull final String friend, @NotNull final FriendModifyAction action) { @@ -439,6 +318,7 @@ public LockReturnValue modifyFriends(@NotNull final String player, @NotNull fina } } default: { + Bukkit.getLogger().warning("modifyFriends: Unknown error occured."); return new LockReturnValue(false); } } @@ -511,31 +391,9 @@ public void applyToOtherContainer(@NotNull Predicate condition, } } - /** - * Clears all values from this block and resets it to the - * defaults. - * - * @since 0.3.2 - */ - public void clear() { - this.setOwner(""); - this.setFriends(Collections.emptyList()); - this.setRedstone(DEFAULT_REDSTONE); - } - - /** - * Merges this handler with another {@link NBTHandler}. - * - * @param handler The handler to merge with. If {@code handler} is not an instance - * of {@link BlockNBTHandler}, this will do nothing. - * @since 0.3.2 - */ @Override - public void mergeHandler(@NotNull NBTHandler handler) { - if (!(handler instanceof BlockNBTHandler)) return; - final BlockNBTHandler blockNBTHandler = (BlockNBTHandler) handler; - this.setOwner(blockNBTHandler.getOwner()); - this.setFriends(blockNBTHandler.getFriends()); - this.setRedstone(blockNBTHandler.getRedstone()); + public @NotNull String getName() { + String name = container.getName(); + return name == null ? "" : name; } } diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/nbt/FriendHandler.java b/spigot/src/main/java/de/sean/blockprot/bukkit/nbt/FriendHandler.java index 4358e210..7d2a155b 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/nbt/FriendHandler.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/nbt/FriendHandler.java @@ -18,6 +18,7 @@ package de.sean.blockprot.bukkit.nbt; +import de.sean.blockprot.nbt.IFriendHandler; import de.tr7zw.changeme.nbtapi.NBTCompound; import org.jetbrains.annotations.NotNull; @@ -31,15 +32,13 @@ * * @since 0.3.0 */ -public final class FriendHandler extends NBTHandler { - static final String ACCESS_FLAGS_ATTRIBUTE = "blockprot_access_flags"; - +public final class FriendHandler extends IFriendHandler { /** * @param compound The NBT compound used. * @since 0.3.0 */ public FriendHandler(@NotNull final NBTCompound compound) { - super(); + super(compound.getName()); this.container = compound; } @@ -48,6 +47,7 @@ public FriendHandler(@NotNull final NBTCompound compound) { * * @since 0.3.0 */ + @Override @NotNull public String getName() { String name = container.getName(); @@ -61,7 +61,7 @@ public String getName() { * @see #getAccessFlags() * @since 0.4.7 */ - private int getAccessFlagsBitset() { + protected int getAccessFlagsBitset() { if (!container.hasKey(ACCESS_FLAGS_ATTRIBUTE)) return BlockAccessFlag.READ.getFlag() | BlockAccessFlag.WRITE.getFlag(); else return container.getInteger(ACCESS_FLAGS_ATTRIBUTE); } @@ -72,7 +72,7 @@ private int getAccessFlagsBitset() { * @param flagsBitset The new bitset. * @since 0.4.7 */ - private void setAccessFlagsBitset(final int flagsBitset) { + protected void setAccessFlagsBitset(final int flagsBitset) { container.setInteger(ACCESS_FLAGS_ATTRIBUTE, flagsBitset); } @@ -101,42 +101,13 @@ public void setAccessFlags(@NotNull final EnumSet flags) { container.setInteger(ACCESS_FLAGS_ATTRIBUTE, flags.stream().mapToInt(BlockAccessFlag::getFlag).sum()); } - /** - * Checks if this player can read the contents of the parents - * block. - * - * @return True, if the player is allowed to see the container's - * contents. - * @since 0.3.0 - */ + @Override public boolean canRead() { return getAccessFlags().contains(BlockAccessFlag.READ); } - /** - * Checks if this player can write the contents of the parents - * block. This means that the player should be allowed to - * take and add items at their will. - * - * @return True, if the player has write access to this block. - * @since 0.3.0 - */ + @Override public boolean canWrite() { return getAccessFlags().contains(BlockAccessFlag.WRITE); } - - /** - * {@inheritDoc} - *

- * This only merges values if {@code handler} is an instance of {@link FriendHandler}, - * and only merges the access flags. - * - * @since 0.4.7 - */ - @Override - public void mergeHandler(@NotNull NBTHandler handler) { - if (handler instanceof FriendHandler) { - this.setAccessFlagsBitset(((FriendHandler) handler).getAccessFlagsBitset()); - } - } } diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/nbt/PlayerSettingsHandler.java b/spigot/src/main/java/de/sean/blockprot/bukkit/nbt/PlayerSettingsHandler.java index 013ceb35..b7e7921c 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/nbt/PlayerSettingsHandler.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/nbt/PlayerSettingsHandler.java @@ -20,6 +20,8 @@ import de.sean.blockprot.bukkit.BlockProt; import de.sean.blockprot.bukkit.inventories.InventoryConstants; +import de.sean.blockprot.nbt.INBTHandler; +import de.sean.blockprot.nbt.IPlayerSettingsHandler; import de.sean.blockprot.util.BlockProtUtil; import de.tr7zw.changeme.nbtapi.NBTCompound; import de.tr7zw.changeme.nbtapi.NBTEntity; @@ -38,23 +40,9 @@ * * @since 0.2.3 */ -public final class PlayerSettingsHandler extends NBTHandler { - static final String LOCK_ON_PLACE_ATTRIBUTE = "splugin_lock_on_place"; - - static final String DEFAULT_FRIENDS_ATTRIBUTE = "blockprot_default_friends"; - - static final String PLAYER_SEARCH_HISTORY = "blockprot_player_search_history"; - +public final class PlayerSettingsHandler extends IPlayerSettingsHandler { private static final int MAX_HISTORY_SIZE = InventoryConstants.tripleLine - 2; - /** - * The player that this settings handler is getting values - * for. - * - * @since 0.2.3 - */ - public final Player player; - /** * Create a new settings handler. * @@ -62,20 +50,14 @@ public final class PlayerSettingsHandler extends NBTHandler { * @since 0.2.3 */ public PlayerSettingsHandler(@NotNull final Player player) { - super(); - this.player = player; - + super(player); this.container = new NBTEntity(player).getPersistentDataContainer(); } /** - * Check if the player wants their blocks to be locked when - * placed. - * - * @return Will return the default setting from the config, or the - * value the player has set it to. - * @since 0.2.3 + * {@inheritDoc} */ + @Override public boolean getLockOnPlace() { // We will default to 'true'. The default value for a boolean is 'false', // which would also be the default value for NBTCompound#getBoolean @@ -85,23 +67,17 @@ public boolean getLockOnPlace() { } /** - * Set the value of the lock on place setting. If true, the - * player wants to lock any block right after placing it. - * - * @param lockOnPlace The boolean value to set it to. - * @since 0.2.3 + * {@inheritDoc} */ - public void setLockOnPlace(final boolean lockOnPlace) { - container.setBoolean(LOCK_ON_PLACE_ATTRIBUTE, lockOnPlace); + @Override + public void setLockOnPlace(final boolean value) { + container.setBoolean(LOCK_ON_PLACE_ATTRIBUTE, value); } /** - * Get the {@link List} of default friends for this player. - * - * @return A List of Player {@link UUID}s as {@link String}s - * representing each friend. - * @since 0.2.3 + * {@inheritDoc} */ + @Override @NotNull public List getDefaultFriends() { if (!container.hasKey(DEFAULT_FRIENDS_ATTRIBUTE)) return new ArrayList<>(); @@ -112,24 +88,17 @@ public List getDefaultFriends() { } /** - * Set a new list of default friends. These have to be UUID-based, - * otherwise other callers using {@link #getDefaultFriends()} will - * experience issues. This does not get checked. - * - * @param friends A list of UUIDs representing a list of friends. - * @since 0.2.3 + * {@inheritDoc} */ + @Override public void setDefaultFriends(@NotNull final List friends) { container.setString(DEFAULT_FRIENDS_ATTRIBUTE, friends.toString()); } /** - * Gets the default friends as a list of {@link OfflinePlayer}. Uses - * {@link #getDefaultFriends} as a base. - * - * @return All default friends as a list of {@link OfflinePlayer}. - * @since 0.2.3 + * {@inheritDoc} */ + @Override @NotNull public List getDefaultFriendsAsPlayers() { ArrayList friends = (ArrayList) getDefaultFriends(); @@ -139,6 +108,12 @@ public List getDefaultFriendsAsPlayers() { .collect(Collectors.toList()); } + @Override + public @NotNull String getName() { + String name = container.getName(); + return name == null ? "" : name; + } + /** * Get the current search history for this player. * @@ -184,7 +159,7 @@ public void addPlayerToSearchHistory(@NotNull final String playerUuid) { * {@inheritDoc} */ @Override - public void mergeHandler(@NotNull NBTHandler handler) { + public void mergeHandler(@NotNull INBTHandler handler) { if (!(handler instanceof PlayerSettingsHandler)) return; final PlayerSettingsHandler playerSettingsHandler = (PlayerSettingsHandler) handler; this.setLockOnPlace(playerSettingsHandler.getLockOnPlace()); diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/TranslationKey.java b/spigot/src/main/java/de/sean/blockprot/bukkit/translation/TranslationKey.java similarity index 98% rename from spigot/src/main/java/de/sean/blockprot/bukkit/TranslationKey.java rename to spigot/src/main/java/de/sean/blockprot/bukkit/translation/TranslationKey.java index 4e055cd3..2c2799a7 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/TranslationKey.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/translation/TranslationKey.java @@ -16,7 +16,7 @@ * along with BlockProt. If not, see . */ -package de.sean.blockprot.bukkit; +package de.sean.blockprot.bukkit.translation; import java.util.Locale; diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/TranslationValue.java b/spigot/src/main/java/de/sean/blockprot/bukkit/translation/TranslationValue.java similarity index 92% rename from spigot/src/main/java/de/sean/blockprot/bukkit/TranslationValue.java rename to spigot/src/main/java/de/sean/blockprot/bukkit/translation/TranslationValue.java index 68a65679..0f43e15e 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/TranslationValue.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/translation/TranslationValue.java @@ -16,9 +16,8 @@ * along with BlockProt. If not, see . */ -package de.sean.blockprot.bukkit; +package de.sean.blockprot.bukkit.translation; -import org.bukkit.configuration.file.YamlConfiguration; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -26,7 +25,7 @@ /** * Represents the default string value and a translated value - * of it, as loaded through {@link Translator#loadFromConfigs(YamlConfiguration, YamlConfiguration)}. + * of it. * * @since 0.4.6 */ @@ -54,7 +53,7 @@ public final class TranslationValue { * @see #setTranslatedValue(String) * @since 0.4.6 */ - TranslationValue(@NotNull final String defaultValue) { + public TranslationValue(@NotNull final String defaultValue) { this.defaultValue = defaultValue; this.translatedValue = UNKNOWN_TRANSLATION; } @@ -106,7 +105,7 @@ public String getTranslatedValue() { * if it is invalid. * @since 0.4.6 */ - protected void setTranslatedValue(@NotNull final String value) { + public void setTranslatedValue(@NotNull final String value) { this.translatedValue = value; } diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/Translator.java b/spigot/src/main/java/de/sean/blockprot/bukkit/translation/Translator.java similarity index 76% rename from spigot/src/main/java/de/sean/blockprot/bukkit/Translator.java rename to spigot/src/main/java/de/sean/blockprot/bukkit/translation/Translator.java index 71cd1337..efb34934 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/Translator.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/translation/Translator.java @@ -16,7 +16,7 @@ * along with BlockProt. If not, see . */ -package de.sean.blockprot.bukkit; +package de.sean.blockprot.bukkit.translation; import com.google.common.collect.Sets; import de.sean.blockprot.util.BlockProtUtil; @@ -49,8 +49,7 @@ public final class Translator { public static final Locale defaultLocale = Locale.UK; /** - * A HashMap of all possible translation values by key, loaded through - * {@link Translator#loadFromConfigs(YamlConfiguration, YamlConfiguration)}. + * A HashMap of all possible translation values by key. * * @since 0.4.6 */ @@ -64,7 +63,7 @@ public final class Translator { * @since 0.4.6 */ @NotNull - private static Locale locale = defaultLocale; + public static Locale locale = defaultLocale; /** * @since 0.2.3 @@ -73,33 +72,47 @@ private Translator() { } /** - * Initialize the translations from given configuration. + * Add a new translation to this Translator. Does not overwrite + * any already present translation. * - * @param config the configuration to load translations from. See - * https://github.com/spnda/BlockProt/blob/master/src/main/resources/translations_en.yml for - * an example. - * @since 0.2.3 - * @deprecated Use {@link #loadFromConfigs(YamlConfiguration, YamlConfiguration)} - * instead, as we now expect default translation values. + * @param key The translation key. + * @param translation The translation value. + * @since 0.4.8 */ - @Deprecated - public static void loadFromConfigs(@NotNull final YamlConfiguration config) { - TranslationKey[] translations = TranslationKey.values(); - for (TranslationKey translation : translations) { - String translationKey = translation.toString(); - if (!config.contains(translationKey, true)) { - continue; - } - Object value = config.get(translationKey); - if (value instanceof String) { - values.put(translation, new TranslationValue("", (String) value)); - } else { - values.put(translation, new TranslationValue( - TranslationValue.UNKNOWN_TRANSLATION, TranslationValue.UNKNOWN_TRANSLATION)); - } + public static void put(@NotNull final TranslationKey key, @NotNull final TranslationValue translation) { + if (!values.containsKey(key)) { + values.put(key, translation); } } + /** + * Get the translated String by translation key. This will use + * {@link TranslationValue#getValue()}, so values that are not + * translated still use their default value. + * + * @param key the translation key to search for. + * @return A translated String or an empty string if not found. + * @since 0.1.10 + */ + @NotNull + public static String get(@NotNull final TranslationKey key) { + TranslationValue value = values.get(key); + return value == null ? "" : value.getValue(); + } + + /** + * Get the currently used for the current translator. This value + * is used to identify the translation file and might be useful + * for knowing the language used by this plugin. + * + * @return The locale of translations. + * @since 0.4.6 + */ + @NotNull + public static Locale getLocale() { + return locale; + } + /** * Initialize the translations from given configuration and sets the * internal locale to a locale, which is read from the configs themselves. @@ -111,7 +124,7 @@ public static void loadFromConfigs(@NotNull final YamlConfiguration config) { * @param config the configuration to load translations from. See * https://github.com/spnda/BlockProt/blob/master/src/main/resources/translations_en.yml for * an example. - * @since 0.4.6 + * @since 0.5.0 */ public static void loadFromConfigs(@NotNull final YamlConfiguration defaultConfig, @NotNull final YamlConfiguration config) { String locale = config.getString("locale"); @@ -141,35 +154,7 @@ public static void loadFromConfigs(@NotNull final YamlConfiguration defaultConfi if (translatedValue instanceof String) { translationValue.setTranslatedValue((String) translatedValue); } - values.put(translation, translationValue); + Translator.put(translation, translationValue); } } - - /** - * Get the translated String by translation key. This will use - * {@link TranslationValue#getValue()}, so values that are not - * translated still use their default value. - * - * @param key the translation key to search for. - * @return A translated String or an empty string if not found. - * @since 0.1.10 - */ - @NotNull - public static String get(@NotNull final TranslationKey key) { - TranslationValue value = values.get(key); - return value == null ? "" : value.getValue(); - } - - /** - * Get the currently used for the current translator. This value - * is used to identify the translation file and might be useful - * for knowing the language used by this plugin. - * - * @return The locale of translations. - * @since 0.4.6 - */ - @NotNull - public static Locale getLocale() { - return locale; - } }