Compare commits

..

49 Commits
5.4.1 ... 5.5.0

Author SHA1 Message Date
Auxilor
54e0b3f482 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	eco-api/src/main/java/com/willfp/eco/internal/arrows/ArrowDataListener.java
#	eco-api/src/main/java/com/willfp/eco/internal/items/AbstractItemStackBuilder.java
#	eco-api/src/main/java/com/willfp/eco/util/TeamUtils.java
2021-06-19 11:38:34 +01:00
Auxilor
93794fe454 Reverted 2021-06-18 11:42:49 +01:00
Auxilor
7f4a0c800e Fixed bug with empty JSON string lists 2021-06-18 09:02:17 +01:00
Auxilor
853864f6f0 Added Paste 2021-06-17 22:23:17 +01:00
Auxilor
0cb6e8f669 Added toPlaintext 2021-06-17 17:45:15 +01:00
Auxilor
d30f657eec Fixed list translation modifying by reference 2021-06-17 13:43:30 +01:00
Auxilor
d60ecdd340 Fixed SkullBuilder 2021-06-17 13:37:47 +01:00
Auxilor
07310df68a Added support for plugin parameters on update methods 2021-06-17 12:57:40 +01:00
Auxilor
5c91aa220a Added LeatherArmorBuilder 2021-06-17 11:33:22 +01:00
Auxilor
756a76057a Reduced generic abuse 2021-06-17 11:28:24 +01:00
Auxilor
b6f27ee232 Refactoring builders to be easier to use 2021-06-17 11:25:54 +01:00
Auxilor
74ca2e82ef Added suppliers to itemstackbuilder 2021-06-17 11:14:47 +01:00
Auxilor
4039439fda Added AbstractItemStackBuilder#setCustomModelData 2021-06-17 11:04:49 +01:00
Auxilor
7dac671690 Added Recipes#createAndRegisterRecipe 2021-06-17 10:56:15 +01:00
Auxilor
411d517a9a Added persistent meta writing to ItemStackBuilder 2021-06-17 10:52:36 +01:00
Auxilor
0d84141116 Updated configs to translate all strings in lists automatically 2021-06-17 10:37:37 +01:00
Auxilor
6bfd5bd153 Added TranslateList and JSON parity 2021-06-17 10:36:38 +01:00
Auxilor
b7d421e1a8 Fixed JSON int bug 2021-06-17 10:28:46 +01:00
Auxilor
2e9d811d3f Fixed deprecated reference 2021-06-17 09:41:53 +01:00
Auxilor
672b295917 Fixed Prerequisite typo 2021-06-17 09:19:42 +01:00
Auxilor
60a83478e8 J16 work 2021-06-17 08:38:18 +01:00
Auxilor
c880a476d4 Continued adding stack support to recipes 2021-06-16 22:17:23 +01:00
Auxilor
692305d595 Continued adding stack support to recipes 2021-06-16 16:54:33 +01:00
Auxilor
9d4cc2961c Fixed NPE 2021-06-16 16:08:45 +01:00
Auxilor
358b389875 Fixed NPE 2021-06-16 16:07:22 +01:00
Auxilor
7fa25c2500 Naming update 2021-06-16 16:04:54 +01:00
Auxilor
91c58c4a53 Added stack support to crafting 2021-06-16 16:03:07 +01:00
Auxilor
4ccee91c64 Added PlayerJumpEvent 2021-06-16 15:45:10 +01:00
Auxilor
eef87342a1 Switched to Java 15 pattern variables 2021-06-16 15:35:15 +01:00
Auxilor
efc70ea7a8 GUI Javadoc 2021-06-16 15:21:48 +01:00
Auxilor
de38299264 Removed test 2021-06-16 15:18:22 +01:00
Auxilor
bc94f43299 Data null safetyx 2021-06-16 13:30:36 +01:00
Auxilor
ed705cc577 Added 1.17 materials to TeamUtils 2021-06-16 11:30:23 +01:00
Auxilor
93410490c5 Javadoc 2021-06-16 11:26:43 +01:00
Auxilor
33914ac284 Added COPPER_ORE to TeamUtils 2021-06-15 21:11:06 +01:00
Auxilor
2acf2ee687 Added setPersistentKEy 2021-06-15 21:08:02 +01:00
Auxilor
0470552168 Added ItemStack builders 2021-06-15 21:04:55 +01:00
Auxilor
3e724eea18 Updated GUI system 2021-06-15 20:44:57 +01:00
Auxilor
33ba5c9d31 Reworked data to just have a call to retrieve a JSON config that can be modified 2021-06-15 15:47:25 +01:00
Auxilor
94ab094952 Cleaning up config 2021-06-15 15:25:45 +01:00
Auxilor
58f5d3f352 Added getKeys(true) 2021-06-15 14:07:55 +01:00
Auxilor
912872e791 Updated config backend 2021-06-15 12:39:10 +01:00
Auxilor
7a65e6e821 Added getSubsections to JSON Configs 2021-06-15 11:29:42 +01:00
Auxilor
3f446f6072 Added JSON support 2021-06-15 11:02:21 +01:00
Auxilor
50f57abd6c Added recursive JSON Get/Set and tests 2021-06-15 10:59:55 +01:00
Auxilor
2c5eae6c6c Removed unused imports 2021-06-15 09:35:12 +01:00
Auxilor
1e3e54b8c5 Added preliminary JSON support 2021-06-14 16:56:10 +01:00
Auxilor
0ce9119a94 Added gson as a dependency 2021-06-14 14:53:16 +01:00
Auxilor
bf76ba9f5a Fixed publication issues 2021-06-13 10:46:57 +01:00
63 changed files with 1887 additions and 316 deletions

View File

@@ -76,6 +76,7 @@ allprojects {
shadowJar {
relocate('org.bstats.bukkit', 'com.willfp.eco.shaded.bstats')
relocate('org.apache.maven', 'com.willfp.eco.shaded.maven')
relocate('com.google.gson', 'com.willfp.eco.shaded.gson')
}
jar {
@@ -86,6 +87,11 @@ allprojects {
onlyIf { !sourceSets.main.allSource.files.isEmpty() }
}
java {
sourceCompatibility = JavaVersion.VERSION_16
targetCompatibility = JavaVersion.VERSION_16
}
compileJava.options.encoding = 'UTF-8'
compileJava.dependsOn clean
@@ -94,5 +100,4 @@ allprojects {
group = 'com.willfp'
archivesBaseName = project.name
version = findProperty("version")
java.sourceCompatibility = JavaVersion.VERSION_16
version = findProperty("version")

View File

@@ -1,15 +1,29 @@
plugins {
id 'com.github.johnrengelman.shadow'
}
group 'com.willfp'
version rootProject.version
dependencies {
compileOnly 'org.spigotmc:spigot:1.16.4-R0.1-SNAPSHOT'
compileOnly 'org.spigotmc:spigot:1.17-R0.1-SNAPSHOT'
compileOnly 'org.apache.maven:maven-artifact:3.0.3'
compileOnly 'org.bstats:bstats-bukkit:1.7'
compileOnly 'com.comphenix.protocol:ProtocolLib:4.6.0-SNAPSHOT'
compileOnly 'me.clip:placeholderapi:2.10.9'
compileOnly 'com.google.code.gson:gson:2.8.7'
}
compileJava.options.encoding = 'UTF-8'
compileJava.dependsOn clean
build.dependsOn publishToMavenLocal
publishing {
publications {
shadow(MavenPublication) {
from components.java
artifactId 'eco'
}
}
}

View File

@@ -272,6 +272,7 @@ public abstract class EcoPlugin extends JavaPlugin {
this.getEventManager().unregisterAllListeners();
this.getScheduler().cancelAll();
this.getConfigHandler().saveAllConfigs();
this.disable();
}

View File

@@ -25,13 +25,22 @@ public class Prerequisite {
);
/**
* Requires the server to be running 1.17
* Requires the server to be running 1.17.
*/
@Deprecated
public static final Prerequisite v1_17 = new Prerequisite(
() -> ProxyConstants.NMS_VERSION.contains("17"),
"Requires server to be running 1.17+"
);
/**
* Requires the server to be running 1.17.
*/
public static final Prerequisite HAS_1_17 = new Prerequisite(
() -> ProxyConstants.NMS_VERSION.contains("17"),
"Requires server to be running 1.17+"
);
/**
* If the necessary prerequisite condition has been met.
*/

View File

@@ -1,6 +1,6 @@
package com.willfp.eco.core.config;
import com.willfp.eco.internal.config.UpdatableYamlConfig;
import com.willfp.eco.internal.config.yaml.UpdatableYamlConfig;
import com.willfp.eco.core.EcoPlugin;
import org.jetbrains.annotations.NotNull;

View File

@@ -11,6 +11,13 @@ public interface Config {
*/
void clearCache();
/**
* Convert the config into readable text.
*
* @return The plaintext.
*/
String toPlaintext();
/**
* Get if the config contains a key.
*
@@ -42,7 +49,7 @@ public interface Config {
* Set an object in config.
* Default implementations call {@link org.bukkit.configuration.file.YamlConfiguration#set(String, Object)}
*
* @param path The path.
* @param path The path.
* @param object The object.
*/
void set(@NotNull String path,

View File

@@ -1,6 +1,6 @@
package com.willfp.eco.core.config;
import com.willfp.eco.internal.config.UpdatableYamlConfig;
import com.willfp.eco.internal.config.yaml.UpdatableYamlConfig;
import com.willfp.eco.core.EcoPlugin;
import org.jetbrains.annotations.NotNull;

View File

@@ -0,0 +1,26 @@
package com.willfp.eco.core.config;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public interface JSONConfig extends Config {
/**
* Get a list of subsections from config.
*
* @param path The key to fetch the value from.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@NotNull
List<JSONConfig> getSubsections(@NotNull String path);
/**
* Get a list of subsections from config.
*
* @param path The key to fetch the value from.
* @return The found value, or null if not found.
*/
@Nullable
List<JSONConfig> getSubsectionsOrNull(@NotNull String path);
}

View File

@@ -0,0 +1,20 @@
package com.willfp.eco.core.config;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.internal.config.json.LoadableJsonConfig;
import org.jetbrains.annotations.NotNull;
public abstract class JsonStaticBaseConfig extends LoadableJsonConfig {
/**
* Config implementation for configs present in the plugin's base directory (eg config.json, lang.json).
* <p>
* Does not automatically update.
*
* @param configName The name of the config
* @param plugin The plugin.
*/
protected JsonStaticBaseConfig(@NotNull final String configName,
@NotNull final EcoPlugin plugin) {
super(configName, plugin, "", plugin.getClass());
}
}

View File

@@ -1,6 +1,6 @@
package com.willfp.eco.core.config;
import com.willfp.eco.internal.config.LoadableYamlConfig;
import com.willfp.eco.internal.config.yaml.LoadableYamlConfig;
import com.willfp.eco.core.EcoPlugin;
import org.jetbrains.annotations.NotNull;

View File

@@ -1,10 +1,10 @@
package com.willfp.eco.core.config;
import com.willfp.eco.internal.config.ConfigWrapper;
import com.willfp.eco.internal.config.yaml.YamlConfigWrapper;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
public abstract class YamlConfig extends ConfigWrapper<YamlConfiguration> {
public abstract class YamlConfig extends YamlConfigWrapper<YamlConfiguration> {
/**
* Config implementation for passing YamlConfigurations.
* <p>

View File

@@ -1,12 +1,13 @@
package com.willfp.eco.core.data;
import com.willfp.eco.core.config.BaseConfig;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.config.Config;
import com.willfp.eco.internal.config.ConfigSection;
import com.willfp.eco.core.config.JSONConfig;
import com.willfp.eco.core.config.JsonStaticBaseConfig;
import com.willfp.eco.internal.config.LoadableConfig;
import com.willfp.eco.internal.config.json.JSONConfigSection;
import lombok.experimental.UtilityClass;
import org.bukkit.NamespacedKey;
import org.bukkit.OfflinePlayer;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
@@ -20,93 +21,21 @@ public class Data {
/**
* Instance of eco data.yml.
*/
private static BaseConfig dataYml = null;
private static JSONConfig datafile = null;
/**
* All cached player data.
*/
private static final Map<UUID, Config> PLAYER_DATA = new HashMap<>();
private static final Map<UUID, Map<EcoPlugin, JSONConfig>> PLAYER_DATA = new HashMap<>();
/**
* Write an integer to a player's data.
* Initialize the player data with an instance of data.json.
*
* @param player The player.
* @param key The key.
* @param data The data.
*/
public void writeInt(@NotNull final OfflinePlayer player,
@NotNull final NamespacedKey key,
final int data) {
getPlayerConfig(player).set(key.toString(), data);
}
/**
* Write a string to a player's data.
*
* @param player The player.
* @param key The key.
* @param data The data.
*/
public void writeString(@NotNull final OfflinePlayer player,
@NotNull final NamespacedKey key,
@NotNull final String data) {
getPlayerConfig(player).set(key.toString(), data);
}
/**
* Write a double to a player's data.
*
* @param player The player.
* @param key The key.
* @param data The data.
*/
public void writeDouble(@NotNull final OfflinePlayer player,
@NotNull final NamespacedKey key,
final double data) {
getPlayerConfig(player).set(key.toString(), data);
}
/**
* Read an integer from a player's data.
*
* @param player The player.
* @param key The key.
*/
public int readInt(@NotNull final OfflinePlayer player,
@NotNull final NamespacedKey key) {
return getPlayerConfig(player).getInt(key.toString());
}
/**
* Read a string from a player's data.
*
* @param player The player.
* @param key The key.
*/
public String readString(@NotNull final OfflinePlayer player,
@NotNull final NamespacedKey key) {
return getPlayerConfig(player).getString(key.toString());
}
/**
* Read a double from a player's data.
*
* @param player The player.
* @param key The key.
*/
public double readDouble(@NotNull final OfflinePlayer player,
@NotNull final NamespacedKey key) {
return getPlayerConfig(player).getDouble(key.toString());
}
/**
* Initialize the player data with an instance of data.yml.
*
* @param config data.yml.
* @param config data.json.
*/
@ApiStatus.Internal
public void init(@NotNull final BaseConfig config) {
dataYml = config;
public void init(@NotNull final JsonStaticBaseConfig config) {
datafile = config;
}
/**
@@ -116,25 +45,39 @@ public class Data {
* @throws IOException Error during saving.
*/
@ApiStatus.Internal
public void save(@NotNull final BaseConfig config) throws IOException {
for (Map.Entry<UUID, Config> entry : PLAYER_DATA.entrySet()) {
for (String key : entry.getValue().getKeys(false)) {
config.set("player-data." + entry.getKey().toString() + "." + key, entry.getValue().get(key));
}
public void save(@NotNull final Config config) throws IOException {
for (Map.Entry<UUID, Map<EcoPlugin, JSONConfig>> entry : PLAYER_DATA.entrySet()) {
entry.getValue().forEach((plugin, jsonConfig) -> {
for (String key : jsonConfig.getKeys(false)) {
config.set("player-data." + plugin.getName().toLowerCase() + "." + entry.getKey().toString() + "." + key, jsonConfig);
}
});
}
config.save();
((LoadableConfig) config).save();
}
private Config getPlayerConfig(@NotNull final OfflinePlayer player) {
Config config = PLAYER_DATA.get(player.getUniqueId());
/**
* Get the data for a player.
*
* @param player The player.
* @param plugin The plugin.
* @return The data.
*/
public JSONConfig getData(@NotNull final OfflinePlayer player,
@NotNull final EcoPlugin plugin) {
if (!PLAYER_DATA.containsKey(player.getUniqueId())) {
PLAYER_DATA.put(player.getUniqueId(), new HashMap<>());
}
JSONConfig config = PLAYER_DATA.get(player.getUniqueId()).get(plugin);
if (config == null) {
config = dataYml.getSubsectionOrNull("player-data." + player.getUniqueId());
config = (JSONConfig) datafile.getSubsectionOrNull("player-data." + plugin.getName().toLowerCase() + "." + player.getUniqueId());
if (config == null) {
config = new ConfigSection(new YamlConfiguration());
config = new JSONConfigSection(new HashMap<>());
}
PLAYER_DATA.put(player.getUniqueId(), config);
return getPlayerConfig(player);
PLAYER_DATA.get(player.getUniqueId()).put(plugin, config);
return getData(player, plugin);
}
return config;

View File

@@ -0,0 +1,40 @@
package com.willfp.eco.core.events;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerMoveEvent;
import org.jetbrains.annotations.NotNull;
public class PlayerJumpEvent extends PlayerMoveEvent {
/**
* Internal bukkit.
*/
private static final HandlerList HANDLERS = new HandlerList();
/**
* Create a new PlayerJumpEvent.
*
* @param event The PlayerMoveEvent.
*/
public PlayerJumpEvent(@NotNull final PlayerMoveEvent event) {
super(event.getPlayer(), event.getFrom(), event.getTo());
}
/**
* Internal bukkit.
*
* @return The handlers.
*/
@Override
public @NotNull HandlerList getHandlers() {
return HANDLERS;
}
/**
* Internal bukkit.
*
* @return The handlers.
*/
public static @NotNull HandlerList getHandlerList() {
return HANDLERS;
}
}

View File

@@ -4,5 +4,11 @@ import org.bukkit.metadata.FixedMetadataValue;
import org.jetbrains.annotations.NotNull;
public interface MetadataValueFactory {
/**
* Create a metadata value for a given plugin and object.
*
* @param value The object to store in metadata.
* @return The metadata value.
*/
FixedMetadataValue create(@NotNull Object value);
}

View File

@@ -1,20 +1,29 @@
package com.willfp.eco.core.gui.menu;
import com.willfp.eco.core.gui.slot.Slot;
import com.willfp.eco.core.items.builder.ItemStackBuilder;
import com.willfp.eco.internal.gui.FillerSlot;
import com.willfp.eco.util.ListUtils;
import lombok.Getter;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class FillerMask {
/**
* Mask.
*/
@Getter
private final List<List<Slot>> mask;
/**
* Create a new filler mask.
*
* @param material The mask material.
* @param pattern The pattern.
*/
public FillerMask(@NotNull final Material material,
@NotNull final String... pattern) {
if (material == Material.AIR) {
@@ -23,11 +32,9 @@ public class FillerMask {
mask = ListUtils.create2DList(6, 9);
ItemStack itemStack = new ItemStack(material);
ItemMeta meta = itemStack.getItemMeta();
assert meta != null;
meta.setDisplayName("§r");
itemStack.setItemMeta(meta);
ItemStack itemStack = new ItemStackBuilder(material)
.setDisplayName("&r")
.build();
int row = 0;

View File

@@ -16,24 +16,72 @@ import java.util.List;
import java.util.function.Consumer;
public interface Menu {
/**
* Get the amount of rows.
*
* @return
*/
int getRows();
/**
* Get slot at given row and column.
*
* @param row The row.
* @param column The column.
* @return The row.
*/
Slot getSlot(int row,
int column);
/**
* Get the menu title.
*
* @return The title.
*/
String getTitle();
/**
* Open the inventory for the player.
*
* @param player The player.
* @return The inventory.
*/
Inventory open(@NotNull Player player);
/**
* Create a builder with a given amount of rows.
*
* @param rows The rows.
* @return The builder.
*/
static Builder builder(final int rows) {
return new Builder(rows);
}
class Builder {
/**
* The amount of rows.
*/
private final int rows;
/**
* The title.
*/
private String title = "Menu";
/**
* The mask slots.
*/
private List<List<Slot>> maskSlots;
/**
* The slots.
*/
private final List<List<Slot>> slots;
/**
* The close event handler.
*/
private Consumer<InventoryCloseEvent> onClose = (event) -> {
};

View File

@@ -1,34 +1,76 @@
package com.willfp.eco.core.gui.slot;
import com.willfp.eco.internal.gui.EcoSlot;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.util.function.BiConsumer;
import java.util.function.Function;
public interface Slot {
ItemStack getItemStack();
/**
* Get the ItemStack that would be shown to a player.
*
* @param player The player.
* @return The ItemStack.
*/
ItemStack getItemStack(@NotNull Player player);
/**
* Create a builder for an ItemStack.
*
* @param itemStack The ItemStack.
* @return The builder.
*/
static Builder builder(@NotNull final ItemStack itemStack) {
return new Builder(itemStack);
return new Builder((player) -> itemStack);
}
/**
* Create a builder for a player-specific ItemStack.
*
* @param provider The provider.
* @return The builder.
*/
static Builder builder(@NotNull final Function<Player, ItemStack> provider) {
return new Builder(provider);
}
class Builder {
private final ItemStack itemStack;
/**
* Provider.
*/
private final Function<Player, ItemStack> provider;
/**
* Left click handler.
*/
private BiConsumer<InventoryClickEvent, Slot> onLeftClick = null;
/**
* Right click handler.
*/
private BiConsumer<InventoryClickEvent, Slot> onRightClick = null;
/**
* Shift-Left-Click handler.
*/
private BiConsumer<InventoryClickEvent, Slot> onShiftLeftClick = null;
/**
* Shift-Right-Click handler.
*/
private BiConsumer<InventoryClickEvent, Slot> onShiftRightClick = null;
/**
* Middle click handler.
*/
private BiConsumer<InventoryClickEvent, Slot> onMiddleClick = null;
Builder(@NotNull final ItemStack itemStack) {
this.itemStack = itemStack;
Builder(@NotNull final Function<Player, ItemStack> provider) {
this.provider = provider;
}
public Builder onLeftClick(@NotNull final BiConsumer<InventoryClickEvent, Slot> action) {
@@ -57,7 +99,7 @@ public interface Slot {
}
public Slot build() {
return new EcoSlot(itemStack, onLeftClick, onRightClick, onShiftLeftClick, onShiftRightClick, onMiddleClick);
return new EcoSlot(provider, onLeftClick, onRightClick, onShiftLeftClick, onShiftRightClick, onMiddleClick);
}
}
}

View File

@@ -52,7 +52,7 @@ public class PlaceholderManager {
public static String getResult(@Nullable final Player player,
@NotNull final String identifier) {
Optional<PlaceholderEntry> matching = REGISTERED_PLACEHOLDERS.stream().filter(expansion -> expansion.getIdentifier().equalsIgnoreCase(identifier)).findFirst();
if (!matching.isPresent()) {
if (matching.isEmpty()) {
return null;
}
PlaceholderEntry entry = matching.get();

View File

@@ -2,6 +2,7 @@ package com.willfp.eco.core.items;
import com.willfp.eco.core.recipe.parts.EmptyTestableItem;
import com.willfp.eco.core.recipe.parts.MaterialTestableItem;
import com.willfp.eco.core.recipe.parts.TestableStack;
import lombok.experimental.UtilityClass;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
@@ -40,6 +41,7 @@ public final class Items {
*/
public TestableItem lookup(@NotNull final String key) {
String[] split = key.toLowerCase().split(":");
if (split.length == 1) {
Material material = Material.getMaterial(key.toUpperCase());
if (material == null || material == Material.AIR) {
@@ -48,8 +50,26 @@ public final class Items {
return new MaterialTestableItem(material);
}
CustomItem part = REGISTRY.get(new NamespacedKey(split[0], split[1]));
return part == null ? new EmptyTestableItem() : part;
if (split.length == 2) {
CustomItem part = REGISTRY.get(new NamespacedKey(split[0], split[1]));
if (part == null) {
Material material = Material.getMaterial(split[0].toUpperCase());
if (material == null || material == Material.AIR) {
return new EmptyTestableItem();
}
return new TestableStack(new MaterialTestableItem(material), Integer.parseInt(split[1]));
} else {
return part;
}
}
if (split.length == 3) {
CustomItem part = REGISTRY.get(new NamespacedKey(split[0], split[1]));
return part == null ? new EmptyTestableItem() : new TestableStack(part, Integer.parseInt(split[2]));
}
return new EmptyTestableItem();
}
/**

View File

@@ -0,0 +1,29 @@
package com.willfp.eco.core.items.builder;
import com.willfp.eco.internal.items.AbstractItemStackBuilder;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
import org.jetbrains.annotations.NotNull;
public class EnchantedBookBuilder extends AbstractItemStackBuilder<EnchantmentStorageMeta, EnchantedBookBuilder> {
/**
* Create a new EnchantedBookBuilder.
*/
public EnchantedBookBuilder() {
super(Material.ENCHANTED_BOOK);
}
/**
* Add an enchantment to the item.
*
* @param enchantment The enchantment.
* @param level The level.
* @return The builder.
*/
public EnchantedBookBuilder addStoredEnchantment(@NotNull final Enchantment enchantment,
final int level) {
this.getMeta().addStoredEnchant(enchantment, level, true);
return this;
}
}

View File

@@ -0,0 +1,181 @@
package com.willfp.eco.core.items.builder;
import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.function.Supplier;
public interface ItemBuilder {
/**
* Set the ItemStack amount.
*
* @param amount The amount.
* @return The builder.
*/
ItemBuilder setAmount(int amount);
/**
* Set the ItemStack amount.
*
* @param amount The amount.
* @return The builder.
*/
ItemBuilder setAmount(@NotNull Supplier<Integer> amount);
/**
* Add an enchantment to the item.
*
* @param enchantment The enchantment.
* @param level The level.
* @return The builder.r
*/
ItemBuilder addEnchantment(@NotNull Enchantment enchantment,
int level);
/**
* Add an enchantment to the item.
*
* @param enchantment The enchantment.
* @param level The level.
* @return The builder.
*/
ItemBuilder addEnchantment(@NotNull Supplier<Enchantment> enchantment,
@NotNull Supplier<Integer> level);
/**
* Set the item display name.
*
* @param name The name.
* @return The builder.
*/
ItemBuilder setDisplayName(@NotNull String name);
/**
* Set the item display name.
*
* @param name The name.
* @return The builder.
*/
ItemBuilder setDisplayName(@NotNull Supplier<String> name);
/**
* Add lore line.
*
* @param line The line.
* @return The builder.
*/
ItemBuilder addLoreLine(@NotNull String line);
/**
* Add lore line.
*
* @param line The line.
* @return The builder.
*/
ItemBuilder addLoreLine(@NotNull Supplier<String> line);
/**
* Add lore lines.
*
* @param lines The lines.
* @return The builder.
*/
ItemBuilder addLoreLines(@NotNull List<String> lines);
/**
* Add lore lines.
*
* @param lines The lines.
* @return The builder.
*/
ItemBuilder addLoreLines(@NotNull Supplier<List<String>> lines);
/**
* Add ItemFlags.
*
* @param itemFlags The flags.
* @return The builder.
*/
ItemBuilder addItemFlag(@NotNull ItemFlag... itemFlags);
/**
* Add ItemFlags.
*
* @param itemFlags The flags.
* @return The builder.
*/
ItemBuilder addItemFlag(@NotNull Supplier<ItemFlag[]> itemFlags);
/**
* Write meta key.
*
* @param key The key.
* @param type The type.
* @param value The value.
* @param <A> The type.
* @param <B> The type.
* @return The builder.
*/
<A, B> ItemBuilder writeMetaKey(@NotNull NamespacedKey key,
@NotNull PersistentDataType<A, B> type,
@NotNull B value);
/**
* Write meta key.
*
* @param key The key.
* @param type The type.
* @param value The value.
* @param <A> The type.
* @param <B> The type.
* @return The builder.
*/
<A, B> ItemBuilder writeMetaKey(@NotNull Supplier<NamespacedKey> key,
@NotNull Supplier<PersistentDataType<A, B>> type,
@NotNull Supplier<B> value);
/**
* Set unbreakable.
*
* @param unbreakable If the item should be unbreakable.
* @return The builder.
*/
ItemBuilder setUnbreakable(boolean unbreakable);
/**
* Set unbreakable.
*
* @param unbreakable If the item should be unbreakable.
* @return The builder.
*/
ItemBuilder setUnbreakable(@NotNull Supplier<Boolean> unbreakable);
/**
* Set custom model data.
*
* @param data The data.
* @return The builder.
*/
ItemBuilder setCustomModelData(@Nullable Integer data);
/**
* Set custom model data.
*
* @param data The data.
* @return The builder.
*/
ItemBuilder setCustomModelData(@NotNull Supplier<Integer> data);
/**
* Build the item.
*
* @return The item.
*/
ItemStack build();
}

View File

@@ -0,0 +1,27 @@
package com.willfp.eco.core.items.builder;
import com.willfp.eco.internal.items.AbstractItemStackBuilder;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
public class ItemStackBuilder extends AbstractItemStackBuilder<ItemMeta, ItemStackBuilder> {
/**
* Create a new ItemStackBuilder.
*
* @param material The material.
*/
public ItemStackBuilder(@NotNull final Material material) {
super(material);
}
/**
* Create a new ItemStackBuilder to modify an existing item.
*
* @param base The ItemStack to start with.
*/
public ItemStackBuilder(@NotNull final ItemStack base) {
super(base);
}
}

View File

@@ -0,0 +1,41 @@
package com.willfp.eco.core.items.builder;
import com.willfp.eco.internal.items.AbstractItemStackBuilder;
import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.LeatherArmorMeta;
import org.jetbrains.annotations.NotNull;
public class LeatherArmorBuilder extends AbstractItemStackBuilder<LeatherArmorMeta, LeatherArmorBuilder> {
/**
* Create a new ItemStackBuilder.
*
* @param material The material.
*/
public LeatherArmorBuilder(@NotNull final Material material) {
super(material);
}
/**
* Create a new ItemStackBuilder to modify an existing item.
*
* @param base The ItemStack to start with.
*/
public LeatherArmorBuilder(@NotNull final ItemStack base) {
super(base);
}
/**
* Set leather color.
*
* @param color The color.
* @return The builder.
*/
public LeatherArmorBuilder setColor(@NotNull final java.awt.Color color) {
Color bukkitColor = Color.fromRGB(color.getRed(), color.getGreen(), color.getBlue());
this.getMeta().setColor(bukkitColor);
return this;
}
}

View File

@@ -0,0 +1,28 @@
package com.willfp.eco.core.items.builder;
import com.willfp.eco.internal.items.AbstractItemStackBuilder;
import com.willfp.eco.util.SkullUtils;
import org.bukkit.Material;
import org.bukkit.inventory.meta.SkullMeta;
import org.jetbrains.annotations.NotNull;
public class SkullBuilder extends AbstractItemStackBuilder<SkullMeta, SkullBuilder> {
/**
* Create a new EnchantedBookBuilder.
*/
public SkullBuilder() {
super(Material.PLAYER_HEAD);
}
/**
* Set skull texture.
*
* @param texture The texture.
* @return The builder.
*/
public SkullBuilder setSkullTexture(@NotNull final String texture) {
SkullUtils.setSkullTexture(this.getMeta(), texture);
return this;
}
}

View File

@@ -2,13 +2,18 @@ package com.willfp.eco.core.recipe;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.items.Items;
import com.willfp.eco.core.recipe.recipes.CraftingRecipe;
import com.willfp.eco.core.recipe.recipes.ShapedCraftingRecipe;
import lombok.experimental.UtilityClass;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@UtilityClass
@SuppressWarnings("deprecation")
public class Recipes {
@@ -59,4 +64,29 @@ public class Recipes {
return null;
}
/**
* Create and register recipe.
*
* @param plugin The plugin.
* @param key The key.
* @param output The output.
* @param recipeStrings The recipe.
* @return The recipe.
*/
public CraftingRecipe createAndRegisterRecipe(@NotNull final EcoPlugin plugin,
@NotNull final String key,
@NotNull final ItemStack output,
@NotNull final List<String> recipeStrings) {
ShapedCraftingRecipe.Builder builder = ShapedCraftingRecipe.builder(plugin, key).setOutput(output);
for (int i = 0; i < 9; i++) {
builder.setRecipePart(i, Items.lookup(recipeStrings.get(i)));
}
ShapedCraftingRecipe recipe = builder.build();
recipe.register();
return recipe;
}
}

View File

@@ -0,0 +1,70 @@
package com.willfp.eco.core.recipe.parts;
import com.willfp.eco.core.items.TestableItem;
import com.willfp.eco.internal.InternalInterfacing;
import lombok.Getter;
import org.apache.commons.lang.Validate;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
public class TestableStack implements TestableItem {
/**
* The item.
*/
private final TestableItem handle;
/**
* The amount.
*/
@Getter
private final int amount;
/**
* Create a new testable stack.
*
* @param item The item.
* @param amount The amount.
*/
public TestableStack(@NotNull final TestableItem item,
final int amount) {
Validate.isTrue(!(item instanceof TestableStack));
this.handle = item;
this.amount = amount;
}
/**
* If the item matches the material.
*
* @param itemStack The item to test.
* @return If the item is of the specified material.
*/
@Override
public boolean matches(@Nullable final ItemStack itemStack) {
return itemStack != null && handle.matches(itemStack) && itemStack.getAmount() >= amount;
}
@Override
public ItemStack getItem() {
ItemStack temp = handle.getItem().clone();
ItemMeta meta = temp.getItemMeta();
assert meta != null;
List<String> lore = meta.hasLore() ? meta.getLore() : new ArrayList<>();
assert lore != null;
lore.add("");
String add = InternalInterfacing.getInstance().getLang().getString("multiple-in-craft");
add = add.replace("%amount%", String.valueOf(amount));
lore.add(add);
meta.setLore(lore);
temp.setItemMeta(meta);
temp.setAmount(amount);
return temp;
}
}

View File

@@ -0,0 +1,69 @@
package com.willfp.eco.core.web;
import org.jetbrains.annotations.NotNull;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class Paste {
/**
* The contents.
*/
private final String contents;
/**
* Create a new paste.
*
* @param contents The contents.
*/
public Paste(@NotNull final String contents) {
this.contents = contents;
}
/**
* Upload to hastebin and get a token.
*
* @return The token.
*/
public String getHastebinToken() {
try {
String urly = "https://hastebin.com/documents";
URL obj = new URL(urly);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/json");
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(contents);
wr.flush();
wr.close();
BufferedReader iny = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String output;
StringBuilder responseBuilder = new StringBuilder();
while ((output = iny.readLine()) != null) {
responseBuilder.append(output);
}
iny.close();
String responseString = responseBuilder.toString();
responseString = responseString.replace("{\"key\":\"", "");
responseString = responseString.replace("\"}", "");
return responseString;
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
}

View File

@@ -0,0 +1,18 @@
package com.willfp.eco.internal;
import com.willfp.eco.core.config.base.LangYml;
import org.jetbrains.annotations.NotNull;
public abstract class InternalInterfacing {
private static InternalInterfacing interfacing;
public static void setInterfacing(@NotNull final InternalInterfacing interfacing) {
InternalInterfacing.interfacing = interfacing;
}
public abstract LangYml getLang();
public static InternalInterfacing getInstance() {
return interfacing;
}
}

View File

@@ -31,14 +31,13 @@ public class ArrowDataListener extends PluginDependent implements Listener {
*/
@EventHandler(priority = EventPriority.LOWEST)
public void onLaunch(final ProjectileLaunchEvent event) {
if (!(event.getEntity() instanceof Arrow)) {
if (!(event.getEntity() instanceof Arrow arrow)) {
return;
}
if (!(event.getEntity().getShooter() instanceof LivingEntity)) {
return;
}
Arrow arrow = (Arrow) event.getEntity();
LivingEntity entity = (LivingEntity) arrow.getShooter();
if (entity.getEquipment() == null) {

View File

@@ -0,0 +1,39 @@
package com.willfp.eco.internal.config;
import java.io.File;
import java.io.IOException;
public interface LoadableConfig {
/**
* Create the file.
*/
void createFile();
/**
* Get resource path as relative to base directory.
*
* @return The resource path.
*/
String getResourcePath();
/**
* Save the config.
*
* @throws IOException If error in saving.
*/
void save() throws IOException;
/**
* Get the config file.
*
* @return The file.
*/
File getConfigFile();
/**
* Get the config name (including extension)
*
* @return The name.
*/
String getName();
}

View File

@@ -0,0 +1,16 @@
package com.willfp.eco.internal.config.json;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
public class JSONConfigSection extends JSONConfigWrapper {
/**
* Config section.
*
* @param values The values.
*/
public JSONConfigSection(@NotNull final Map<String, Object> values) {
this.init(values);
}
}

View File

@@ -0,0 +1,345 @@
package com.willfp.eco.internal.config.json;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.willfp.eco.core.config.Config;
import com.willfp.eco.core.config.JSONConfig;
import com.willfp.eco.util.StringUtils;
import lombok.Getter;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.ConfigurationSection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
@SuppressWarnings({"unchecked", "unused"})
public abstract class JSONConfigWrapper implements JSONConfig, Cloneable {
/**
* The linked {@link ConfigurationSection} where values are physically stored.
*/
@Getter
private final Gson handle = new GsonBuilder().setPrettyPrinting().create();
/**
* All stored values.
*/
@Getter
private final Map<String, Object> values = new HashMap<>();
/**
* All cached values.
*/
@Getter
private final Map<String, Object> cache = new HashMap<>();
/**
* Abstract config.
*/
protected JSONConfigWrapper() {
}
public void init(@NotNull final Map<String, Object> values) {
this.values.clear();
this.values.putAll(values);
}
@Override
public final void clearCache() {
cache.clear();
}
@Override
public String toPlaintext() {
return this.getHandle().toJson(this.getValues());
}
@Override
public boolean has(@NotNull final String path) {
return getOfKnownType(path, Object.class) != null;
}
@Nullable
protected <T> T getOfKnownType(@NotNull final String path,
@NotNull final Class<T> clazz) {
return getOfKnownType(path, clazz, true);
}
@Nullable
protected <T> T getOfKnownType(@NotNull final String path,
@NotNull final Class<T> clazz,
final boolean isBase) {
String closestPath = path;
if (cache.containsKey(path) && isBase) {
return (T) cache.get(path);
}
if (path.contains(".")) {
String[] split = path.split("\\.");
closestPath = split[0];
}
if (values.get(closestPath) instanceof Map && !path.equals(closestPath)) {
JSONConfigSection section = new JSONConfigSection((Map<String, Object>) values.get(closestPath));
return section.getOfKnownType(path.substring(closestPath.length() + 1), clazz, false);
} else {
if (values.containsKey(closestPath)) {
return (T) values.get(closestPath);
} else {
return null;
}
}
}
@NotNull
@Override
public List<String> getKeys(final boolean deep) {
if (deep) {
return new ArrayList<>(getDeepKeys(new HashSet<>(), ""));
} else {
return new ArrayList<>(values.keySet());
}
}
protected Set<String> getDeepKeys(@NotNull final Set<String> list,
@NotNull final String root) {
for (String key : values.keySet()) {
list.add(root + key);
if (values.get(key) instanceof Map) {
JSONConfigSection section = new JSONConfigSection((Map<String, Object>) values.get(key));
list.addAll(section.getDeepKeys(list, root + key + "."));
}
}
return list;
}
@Override
@Nullable
public Object get(@NotNull final String path) {
return getOfKnownType(path, Object.class);
}
@Override
public void set(@NotNull final String path,
@Nullable final Object object) {
setRecursively(path, object, true);
clearCache();
}
protected void setRecursively(@NotNull final String path,
@Nullable final Object object,
final boolean isBase) {
String closestPath = path;
if (path.contains(".")) {
String[] split = path.split("\\.");
closestPath = split[0];
}
if (values.get(closestPath) instanceof Map && !path.equals(closestPath)) {
JSONConfigSection section = new JSONConfigSection((Map<String, Object>) values.get(closestPath));
section.setRecursively(path.substring(closestPath.length() + 1), object, false);
values.put(closestPath, section.getValues());
} else {
Object obj = object;
if (object instanceof JSONConfig) {
obj = ((JSONConfigWrapper) object).getValues();
}
values.put(path, obj);
}
}
@Override
@NotNull
public Config getSubsection(@NotNull final String path) {
Config subsection = getSubsectionOrNull(path);
Validate.notNull(subsection);
return subsection;
}
@Override
@Nullable
public Config getSubsectionOrNull(@NotNull final String path) {
if (values.containsKey(path)) {
Map<String, Object> subsection = (Map<String, Object>) values.get(path);
return new JSONConfigSection(subsection);
} else {
return null;
}
}
@Override
@NotNull
public List<JSONConfig> getSubsections(@NotNull final String path) {
List<JSONConfig> subsections = getSubsectionsOrNull(path);
Validate.notNull(subsections);
return subsections;
}
@Override
@Nullable
public List<JSONConfig> getSubsectionsOrNull(@NotNull final String path) {
List<Map<String, Object>> maps = (List<Map<String, Object>>) getOfKnownType(path, Object.class);
if (maps == null) {
return null;
}
List<JSONConfig> configs = new ArrayList<>();
for (Map<String, Object> map : maps) {
configs.add(new JSONConfigSection(map));
}
return configs;
}
@Override
public int getInt(@NotNull final String path) {
// ew
return Objects.requireNonNullElse(getOfKnownType(path, Double.class), 0D).intValue();
}
@Override
@Nullable
public Integer getIntOrNull(@NotNull final String path) {
if (has(path)) {
return getInt(path);
} else {
return null;
}
}
@Override
public int getInt(@NotNull final String path,
final int def) {
return Objects.requireNonNullElse(getOfKnownType(path, Integer.class), def);
}
@Override
@NotNull
public List<Integer> getInts(@NotNull final String path) {
return (List<Integer>) Objects.requireNonNullElse(getOfKnownType(path, Object.class), new ArrayList<>());
}
@Override
@Nullable
public List<Integer> getIntsOrNull(@NotNull final String path) {
if (has(path)) {
return getInts(path);
} else {
return null;
}
}
@Override
public boolean getBool(@NotNull final String path) {
return Objects.requireNonNullElse(getOfKnownType(path, Boolean.class), false);
}
@Override
@Nullable
public Boolean getBoolOrNull(@NotNull final String path) {
if (has(path)) {
return getBool(path);
} else {
return null;
}
}
@Override
@NotNull
public List<Boolean> getBools(@NotNull final String path) {
return (List<Boolean>) Objects.requireNonNullElse(getOfKnownType(path, Object.class), new ArrayList<>());
}
@Override
@Nullable
public List<Boolean> getBoolsOrNull(@NotNull final String path) {
if (has(path)) {
return getBools(path);
} else {
return null;
}
}
@Override
@NotNull
public String getString(@NotNull final String path) {
return StringUtils.translate(Objects.requireNonNullElse(getOfKnownType(path, String.class), ""));
}
@Override
@Nullable
public String getStringOrNull(@NotNull final String path) {
if (has(path)) {
return getString(path);
} else {
return null;
}
}
@Override
@NotNull
public List<String> getStrings(@NotNull final String path) {
return StringUtils.translateList((List<String>) Objects.requireNonNullElse(getOfKnownType(path, Object.class), new ArrayList<>()));
}
@Override
@Nullable
public List<String> getStringsOrNull(@NotNull final String path) {
if (has(path)) {
return getStrings(path);
} else {
return null;
}
}
@Override
public double getDouble(@NotNull final String path) {
return Objects.requireNonNullElse(getOfKnownType(path, Double.class), 0D);
}
@Override
@Nullable
public Double getDoubleOrNull(@NotNull final String path) {
if (has(path)) {
return getDouble(path);
} else {
return null;
}
}
@Override
@NotNull
public List<Double> getDoubles(@NotNull final String path) {
return (List<Double>) Objects.requireNonNullElse(getOfKnownType(path, Object.class), new ArrayList<>());
}
@Override
@Nullable
public List<Double> getDoublesOrNull(@NotNull final String path) {
if (has(path)) {
return getDoubles(path);
} else {
return null;
}
}
@Override
public JSONConfigWrapper clone() {
return new JSONConfigSection(new HashMap<>(this.getValues()));
}
}

View File

@@ -0,0 +1,155 @@
package com.willfp.eco.internal.config.json;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.internal.config.LoadableConfig;
import lombok.AccessLevel;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.util.HashMap;
@SuppressWarnings({"unchecked", "unused"})
public abstract class LoadableJsonConfig extends JSONConfigWrapper implements LoadableConfig {
/**
* The physical config file, as stored on disk.
*/
@Getter
private final File configFile;
/**
* Plugin handle.
*/
@Getter(AccessLevel.PROTECTED)
private final EcoPlugin plugin;
/**
* The full name of the config file (eg config.json).
*/
@Getter
private final String name;
/**
* The subdirectory path.
*/
@Getter(AccessLevel.PROTECTED)
private final String subDirectoryPath;
/**
* The provider of the config.
*/
@Getter(AccessLevel.PROTECTED)
private final Class<?> source;
/**
* Abstract config.
*
* @param configName The name of the config
* @param plugin The plugin.
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
*/
protected LoadableJsonConfig(@NotNull final String configName,
@NotNull final EcoPlugin plugin,
@NotNull final String subDirectoryPath,
@NotNull final Class<?> source) {
this.plugin = plugin;
this.name = configName + ".json";
this.source = source;
this.subDirectoryPath = subDirectoryPath;
File directory = new File(this.getPlugin().getDataFolder(), subDirectoryPath);
if (!directory.exists()) {
directory.mkdirs();
}
if (!new File(directory, this.name).exists()) {
createFile();
}
this.configFile = new File(directory, this.name);
try {
init(this.configFile);
} catch (IOException e) {
e.printStackTrace();
}
plugin.getConfigHandler().addConfig(this);
}
@Override
public void createFile() {
String resourcePath = getResourcePath();
InputStream in = source.getResourceAsStream(resourcePath);
File outFile = new File(this.getPlugin().getDataFolder(), resourcePath);
int lastIndex = resourcePath.lastIndexOf('/');
File outDir = new File(this.getPlugin().getDataFolder(), resourcePath.substring(0, Math.max(lastIndex, 0)));
if (!outDir.exists()) {
outDir.mkdirs();
}
try {
if (!outFile.exists()) {
OutputStream out = new FileOutputStream(outFile);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
out.close();
in.close();
}
} catch (IOException ignored) {
}
}
/**
* Get resource path as relative to base directory.
*
* @return The resource path.
*/
@Override
public String getResourcePath() {
String resourcePath;
if (subDirectoryPath.isEmpty()) {
resourcePath = name;
} else {
resourcePath = subDirectoryPath + name;
}
return "/" + resourcePath;
}
/**
* Save the config.
*
* @throws IOException If error in saving.
*/
@Override
public void save() throws IOException {
configFile.delete();
Files.write(configFile.toPath(), this.toPlaintext().getBytes(), StandardOpenOption.CREATE, StandardOpenOption.WRITE);
}
/**
* Initialize the config.
*
* @param file The config file.
* @throws FileNotFoundException If the file doesn't exist.
*/
public void init(@NotNull final File file) throws FileNotFoundException {
super.init(this.getHandle().fromJson(new FileReader(file), HashMap.class));
}
}

View File

@@ -1,20 +1,29 @@
package com.willfp.eco.internal.config.updating;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginDependent;
import com.willfp.eco.core.config.ConfigUpdater;
import com.willfp.eco.internal.config.LoadableConfig;
import com.willfp.eco.internal.config.updating.exceptions.InvalidUpdatableClassException;
import com.willfp.eco.internal.config.updating.exceptions.InvalidUpdateMethodException;
import com.willfp.eco.core.PluginDependent;
import com.willfp.eco.core.EcoPlugin;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class ConfigHandler extends PluginDependent {
/**
* A set of all configs that can be saved.
*/
private final List<LoadableConfig> configs = new ArrayList<>();
/**
* A set of all classes that can be updated.
*/
@@ -35,15 +44,18 @@ public class ConfigHandler extends PluginDependent {
public void callUpdate() {
updatableClasses.forEach(clazz -> Arrays.stream(clazz.getDeclaredMethods()).forEach(method -> {
if (method.isAnnotationPresent(ConfigUpdater.class)) {
if (method.getParameterTypes().length != 0) {
throw new InvalidUpdateMethodException("Update method must not have parameters.");
}
if (!Modifier.isStatic(method.getModifiers())) {
throw new InvalidUpdateMethodException("Update method must be static.");
}
try {
method.invoke(null);
if (method.getParameterCount() == 0) {
method.invoke(null);
} else if (method.getParameterCount() == 1) {
method.invoke(null, this.getPlugin());
} else {
throw new InvalidUpdateMethodException("Update method must have 0 parameters or a plugin parameter.");
}
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
throw new InvalidUpdateMethodException("Update method generated an exception.");
@@ -60,7 +72,7 @@ public class ConfigHandler extends PluginDependent {
public void registerUpdatableClass(@NotNull final Class<?> updatableClass) {
boolean isValid = false;
for (Method method : updatableClass.getDeclaredMethods()) {
if (Modifier.isStatic(method.getModifiers()) && method.getParameterTypes().length == 0 && method.isAnnotationPresent(ConfigUpdater.class)) {
if (Modifier.isStatic(method.getModifiers()) && (method.getParameterCount() == 0 || method.getParameterCount() == 1) && method.isAnnotationPresent(ConfigUpdater.class)) {
isValid = true;
break;
}
@@ -72,4 +84,25 @@ public class ConfigHandler extends PluginDependent {
updatableClasses.add(updatableClass);
}
/**
* Save all configs.
*/
public void saveAllConfigs() {
try {
for (LoadableConfig config : configs) {
config.save();
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Add new config to be saved.
* @param config The config.
*/
public void addConfig(@NotNull final LoadableConfig config) {
configs.add(config);
}
}

View File

@@ -1,13 +1,13 @@
package com.willfp.eco.internal.config;
package com.willfp.eco.internal.config.yaml;
import org.bukkit.configuration.ConfigurationSection;
import org.jetbrains.annotations.NotNull;
public class ConfigSection extends ConfigWrapper<ConfigurationSection> {
public class ConfigSection extends YamlConfigWrapper<ConfigurationSection> {
/**
* Config section.
*
* @param section The section.
* @param section The section.
*/
public ConfigSection(@NotNull final ConfigurationSection section) {
this.init(section);

View File

@@ -1,26 +1,23 @@
package com.willfp.eco.internal.config;
package com.willfp.eco.internal.config.yaml;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.internal.config.LoadableConfig;
import lombok.AccessLevel;
import lombok.Getter;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
public abstract class LoadableYamlConfig extends ConfigWrapper<YamlConfiguration> {
public abstract class LoadableYamlConfig extends YamlConfigWrapper<YamlConfiguration> implements LoadableConfig {
/**
* The physical config file, as stored on disk.
*/
@Getter(AccessLevel.PROTECTED)
@Getter
private final File configFile;
/**
@@ -77,7 +74,8 @@ public abstract class LoadableYamlConfig extends ConfigWrapper<YamlConfiguration
init(YamlConfiguration.loadConfiguration(configFile));
}
private void createFile() {
@Override
public void createFile() {
String resourcePath = getResourcePath();
InputStream in = source.getResourceAsStream(resourcePath);
@@ -102,14 +100,12 @@ public abstract class LoadableYamlConfig extends ConfigWrapper<YamlConfiguration
}
} catch (IOException ignored) {
}
plugin.getConfigHandler().addConfig(this);
}
/**
* Get resource path as relative to base directory.
*
* @return The resource path.
*/
protected String getResourcePath() {
@Override
public String getResourcePath() {
String resourcePath;
if (subDirectoryPath.isEmpty()) {
@@ -121,35 +117,7 @@ public abstract class LoadableYamlConfig extends ConfigWrapper<YamlConfiguration
return "/" + resourcePath;
}
/**
* Get YamlConfiguration as found in jar.
*
* @return The YamlConfiguration.
*/
protected YamlConfiguration getConfigInJar() {
InputStream newIn = source.getResourceAsStream(getResourcePath());
if (newIn == null) {
throw new NullPointerException(name + " is null?");
}
BufferedReader reader = new BufferedReader(new InputStreamReader(newIn, StandardCharsets.UTF_8));
YamlConfiguration newConfig = new YamlConfiguration();
try {
newConfig.load(reader);
} catch (IOException | InvalidConfigurationException e) {
e.printStackTrace();
}
return newConfig;
}
/**
* Save the config.
*
* @throws IOException If error in saving.
*/
@Override
public void save() throws IOException {
this.getHandle().save(this.getConfigFile());
}

View File

@@ -1,11 +1,15 @@
package com.willfp.eco.internal.config;
package com.willfp.eco.internal.config.yaml;
import com.willfp.eco.core.EcoPlugin;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -84,4 +88,23 @@ public abstract class UpdatableYamlConfig extends LoadableYamlConfig {
e.printStackTrace();
}
}
public YamlConfiguration getConfigInJar() {
InputStream newIn = this.getSource().getResourceAsStream(getResourcePath());
if (newIn == null) {
throw new NullPointerException(this.getName() + " is null?");
}
BufferedReader reader = new BufferedReader(new InputStreamReader(newIn, StandardCharsets.UTF_8));
YamlConfiguration newConfig = new YamlConfiguration();
try {
newConfig.load(reader);
} catch (IOException | InvalidConfigurationException e) {
e.printStackTrace();
}
return newConfig;
}
}

View File

@@ -1,10 +1,11 @@
package com.willfp.eco.internal.config;
package com.willfp.eco.internal.config.yaml;
import com.willfp.eco.util.StringUtils;
import com.willfp.eco.core.config.Config;
import com.willfp.eco.util.StringUtils;
import lombok.Getter;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -15,7 +16,7 @@ import java.util.Map;
import java.util.Objects;
@SuppressWarnings({"unchecked", "unused"})
public abstract class ConfigWrapper<T extends ConfigurationSection> implements Config {
public abstract class YamlConfigWrapper<T extends ConfigurationSection> implements Config {
/**
* The linked {@link ConfigurationSection} where values are physically stored.
*/
@@ -30,7 +31,7 @@ public abstract class ConfigWrapper<T extends ConfigurationSection> implements C
/**
* Abstract config.
*/
protected ConfigWrapper() {
protected YamlConfigWrapper() {
}
@@ -39,6 +40,15 @@ public abstract class ConfigWrapper<T extends ConfigurationSection> implements C
return this;
}
@Override
public String toPlaintext() {
YamlConfiguration temp = new YamlConfiguration();
for (String key : handle.getKeys(true)) {
temp.set(key, handle.get(key));
}
return temp.saveToString();
}
@Override
public final void clearCache() {
cache.clear();
@@ -210,7 +220,7 @@ public abstract class ConfigWrapper<T extends ConfigurationSection> implements C
@NotNull
public List<String> getStrings(@NotNull final String path) {
if (cache.containsKey(path)) {
return (List<String>) cache.get(path);
return StringUtils.translateList((List<String>) cache.get(path));
} else {
cache.put(path, has(path) ? new ArrayList<>(handle.getStringList(path)) : new ArrayList<>());
return getStrings(path);

View File

@@ -110,11 +110,10 @@ public class EcoExtensionLoader extends PluginDependent implements ExtensionLoad
e.printStackTrace();
}
if (!(object instanceof Extension)) {
if (!(object instanceof Extension extension)) {
throw new MalformedExtensionException(extensionJar.getName() + " is invalid");
}
Extension extension = (Extension) object;
extension.setMetadata(metadata);
extension.enable();
extensions.add(extension);

View File

@@ -59,7 +59,7 @@ public class EcoMenu implements Menu {
if (i == rows * 9) {
break;
}
ItemStack slotItem = item.getItemStack();
ItemStack slotItem = item.getItemStack(player);
ItemMeta meta = slotItem.getItemMeta();
if (meta != null) {
List<String> lore = meta.getLore();

View File

@@ -2,16 +2,18 @@ package com.willfp.eco.internal.gui;
import com.willfp.eco.core.gui.slot.Slot;
import lombok.Getter;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.BiConsumer;
import java.util.function.Function;
public class EcoSlot implements Slot {
@Getter
private final ItemStack itemStack;
private final Function<Player, ItemStack> provider;
private final BiConsumer<InventoryClickEvent, Slot> onLeftClick;
@@ -23,13 +25,13 @@ public class EcoSlot implements Slot {
private final BiConsumer<InventoryClickEvent, Slot> onMiddleClick;
public EcoSlot(@NotNull final ItemStack itemStack,
public EcoSlot(@NotNull final Function<Player, ItemStack> provider,
@Nullable final BiConsumer<InventoryClickEvent, Slot> onLeftClick,
@Nullable final BiConsumer<InventoryClickEvent, Slot> onRightClick,
@Nullable final BiConsumer<InventoryClickEvent, Slot> onShiftLeftClick,
@Nullable final BiConsumer<InventoryClickEvent, Slot> onShiftRightClick,
@Nullable final BiConsumer<InventoryClickEvent, Slot> onMiddleClick) {
this.itemStack = itemStack;
this.provider = provider;
this.onLeftClick = onLeftClick == null ? ((event, slot) -> { }) : onLeftClick;
this.onRightClick = onRightClick == null ? ((event, slot) -> { }) : onRightClick;
this.onShiftLeftClick = onShiftLeftClick == null ? ((event, slot) -> { }) : onShiftLeftClick;
@@ -39,23 +41,17 @@ public class EcoSlot implements Slot {
public void handleInventoryClick(@NotNull final InventoryClickEvent event) {
switch (event.getClick()) {
case LEFT:
this.onLeftClick.accept(event, this);
break;
case RIGHT:
this.onRightClick.accept(event, this);
break;
case SHIFT_LEFT:
this.onShiftLeftClick.accept(event, this);
break;
case SHIFT_RIGHT:
this.onShiftRightClick.accept(event, this);
break;
case MIDDLE:
this.onMiddleClick.accept(event, this);
break;
default:
break;
case LEFT -> this.onLeftClick.accept(event, this);
case RIGHT -> this.onRightClick.accept(event, this);
case SHIFT_LEFT -> this.onShiftLeftClick.accept(event, this);
case SHIFT_RIGHT -> this.onShiftRightClick.accept(event, this);
case MIDDLE -> this.onMiddleClick.accept(event, this);
default -> { }
}
}
@Override
public ItemStack getItemStack(@NotNull final Player player) {
return provider.apply(player);
}
}

View File

@@ -10,6 +10,6 @@ public class FillerSlot extends EcoSlot {
* @param itemStack The ItemStack.
*/
public FillerSlot(@NotNull final ItemStack itemStack) {
super(itemStack, null, null, null, null, null);
super((player) -> itemStack, null, null, null, null, null);
}
}

View File

@@ -0,0 +1,194 @@
package com.willfp.eco.internal.items;
import com.willfp.eco.core.items.builder.ItemBuilder;
import com.willfp.eco.util.StringUtils;
import lombok.AccessLevel;
import lombok.Getter;
import org.apache.commons.lang.Validate;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
@SuppressWarnings("unchecked")
public abstract class AbstractItemStackBuilder<T extends ItemMeta, U extends AbstractItemStackBuilder<T, U>> implements ItemBuilder {
/**
* The ItemMeta used while building.
*/
@Getter(AccessLevel.PROTECTED)
private final T meta;
/**
* The ItemStack.
*/
@Getter(AccessLevel.PROTECTED)
private final ItemStack base;
/**
* Create a new ItemStackBuilder.
*
* @param material The material.
*/
protected AbstractItemStackBuilder(@NotNull final Material material) {
this(new ItemStack(material));
}
/**
* Create a new ItemStackBuilder to modify an existing item.
*
* @param base The ItemStack to start with.
*/
protected AbstractItemStackBuilder(@NotNull final ItemStack base) {
this.base = base;
this.meta = (T) base.getItemMeta();
assert meta != null;
}
@Override
public U setAmount(final int amount) {
Validate.isTrue(amount >= 1 && amount <= base.getMaxStackSize());
base.setAmount(amount);
return (U) this;
}
@Override
public U setAmount(@NotNull final Supplier<Integer> amount) {
return setAmount(amount.get());
}
@Override
public U addEnchantment(@NotNull final Enchantment enchantment,
final int level) {
meta.addEnchant(enchantment, level, true);
return (U) this;
}
@Override
public U addEnchantment(@NotNull final Supplier<Enchantment> enchantment,
@NotNull final Supplier<Integer> level) {
return addEnchantment(enchantment.get(), level.get());
}
@Override
public U setDisplayName(@NotNull final String name) {
meta.setDisplayName(StringUtils.translate(name));
return (U) this;
}
@Override
public U setDisplayName(@NotNull final Supplier<String> name) {
String result = name.get();
return result == null ? (U) this : setDisplayName(name.get());
}
@Override
public U addLoreLine(@NotNull final String line) {
List<String> lore = meta.hasLore() ? meta.getLore() : new ArrayList<>();
assert lore != null;
lore.add(StringUtils.translate(line));
meta.setLore(lore);
return (U) this;
}
@Override
public U addLoreLine(@NotNull final Supplier<String> line) {
String result = line.get();
return result == null ? (U) this : addLoreLine(line.get());
}
@Override
public U addLoreLines(@NotNull final List<String> lines) {
List<String> lore = meta.hasLore() ? meta.getLore() : new ArrayList<>();
assert lore != null;
for (String line : lines) {
lore.add(StringUtils.translate(line));
}
meta.setLore(lore);
return (U) this;
}
@Override
public U addLoreLines(@NotNull final Supplier<List<String>> lines) {
List<String> result = lines.get();
return result == null ? (U) this : addLoreLines(lines.get());
}
@Override
public U addItemFlag(@NotNull final ItemFlag... itemFlags) {
meta.addItemFlags(itemFlags);
return (U) this;
}
@Override
public U addItemFlag(@NotNull final Supplier<ItemFlag[]> itemFlags) {
ItemFlag[] result = itemFlags.get();
return result == null ? (U) this : addItemFlag(result);
}
@Override
public <A, B> U writeMetaKey(@NotNull final NamespacedKey key,
@NotNull final PersistentDataType<A, B> type,
@NotNull final B value) {
meta.getPersistentDataContainer().set(key, type, value);
return (U) this;
}
@Override
public <A, B> U writeMetaKey(@NotNull final Supplier<NamespacedKey> key,
@NotNull final Supplier<PersistentDataType<A, B>> type,
@NotNull final Supplier<B> value) {
return writeMetaKey(key.get(), type.get(), value.get());
}
@Override
public U setUnbreakable(final boolean unbreakable) {
meta.setUnbreakable(unbreakable);
return (U) this;
}
@Override
public U setUnbreakable(@NotNull final Supplier<Boolean> unbreakable) {
Boolean result = unbreakable.get();
return result == null ? (U) this : setUnbreakable(unbreakable);
}
@Override
public U setCustomModelData(@Nullable final Integer data) {
meta.setCustomModelData(data);
return (U) this;
}
@Override
public U setCustomModelData(@NotNull final Supplier<Integer> data) {
Integer result = data.get();
return result == null ? (U) this : setCustomModelData(result);
}
@Override
public ItemStack build() {
base.setItemMeta(meta);
return base;
}
}

View File

@@ -121,8 +121,7 @@ public class DurabilityUtils {
return;
}
if (item.getItemMeta() instanceof Damageable) {
Damageable meta = (Damageable) item.getItemMeta();
if (item.getItemMeta() instanceof Damageable meta) {
meta.setDamage(meta.getDamage() - repair);
if (meta.getDamage() < 0) {

View File

@@ -39,6 +39,33 @@ public class StringUtils {
.add(Pattern.compile("<#" + "([A-Fa-f0-9]{6})" + ">"))
.build();
/**
* Translate a list of strings - converts Placeholders and Color codes.
*
* @param list The messages to translate.
* @param player The player to translate placeholders with respect to.
* @return The message, translated.
*/
public List<String> translateList(@NotNull final List<String> list,
@Nullable final Player player) {
List<String> translated = new ArrayList<>();
for (String string : list) {
translated.add(translate(string, player));
}
return translated;
}
/**
* Translate a list of strings - converts Placeholders and Color codes.
*
* @param list The messages to translate.
* @return The message, translated.
*/
public List<String> translateList(@NotNull final List<String> list) {
return translateList(list, null);
}
/**
* Translate a string - converts Placeholders and Color codes.
*
@@ -79,16 +106,16 @@ public class StringUtils {
@NotNull final Pattern pattern) {
Matcher matcher = pattern.matcher(message);
StringBuffer buffer = new StringBuffer(message.length() + 4 * 8);
StringBuilder builder = new StringBuilder(message.length() + 4 * 8);
while (matcher.find()) {
String group = matcher.group(1);
matcher.appendReplacement(buffer, COLOR_CHAR + "x"
matcher.appendReplacement(builder, COLOR_CHAR + "x"
+ COLOR_CHAR + group.charAt(0) + COLOR_CHAR + group.charAt(1)
+ COLOR_CHAR + group.charAt(2) + COLOR_CHAR + group.charAt(3)
+ COLOR_CHAR + group.charAt(4) + COLOR_CHAR + group.charAt(5));
}
return matcher.appendTail(buffer).toString();
return matcher.appendTail(builder).toString();
}
/**
@@ -198,8 +225,7 @@ public class StringUtils {
return (String) object;
} else if (object instanceof Double) {
return NumberUtils.format((Double) object);
} else if (object instanceof Collection<?>) {
Collection<?> c = (Collection<?>) object;
} else if (object instanceof Collection<?> c) {
return c.stream().map(StringUtils::internalToString).collect(Collectors.joining(", "));
} else {
return String.valueOf(object);

View File

@@ -2,6 +2,7 @@ package com.willfp.eco.util;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.willfp.eco.core.Prerequisite;
import lombok.experimental.UtilityClass;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
@@ -10,6 +11,8 @@ import org.bukkit.scoreboard.Scoreboard;
import org.bukkit.scoreboard.Team;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
@UtilityClass
@@ -17,7 +20,7 @@ public class TeamUtils {
/**
* Ore ChatColors.
*/
private static final BiMap<Material, ChatColor> MATERIAL_COLORS = HashBiMap.create();
private static final Map<Material, ChatColor> MATERIAL_COLORS = new HashMap<>();
/**
* All chat color teams.
@@ -73,13 +76,25 @@ public class TeamUtils {
fromChatColor(value);
}
MATERIAL_COLORS.forcePut(Material.COAL_ORE, ChatColor.BLACK);
MATERIAL_COLORS.forcePut(Material.IRON_ORE, ChatColor.GRAY);
MATERIAL_COLORS.forcePut(Material.GOLD_ORE, ChatColor.YELLOW);
MATERIAL_COLORS.forcePut(Material.LAPIS_ORE, ChatColor.BLUE);
MATERIAL_COLORS.forcePut(Material.REDSTONE_ORE, ChatColor.RED);
MATERIAL_COLORS.forcePut(Material.DIAMOND_ORE, ChatColor.AQUA);
MATERIAL_COLORS.forcePut(Material.EMERALD_ORE, ChatColor.GREEN);
MATERIAL_COLORS.forcePut(Material.ANCIENT_DEBRIS, ChatColor.DARK_RED);
MATERIAL_COLORS.put(Material.COAL_ORE, ChatColor.BLACK);
MATERIAL_COLORS.put(Material.IRON_ORE, ChatColor.GRAY);
MATERIAL_COLORS.put(Material.GOLD_ORE, ChatColor.YELLOW);
MATERIAL_COLORS.put(Material.LAPIS_ORE, ChatColor.BLUE);
MATERIAL_COLORS.put(Material.REDSTONE_ORE, ChatColor.RED);
MATERIAL_COLORS.put(Material.DIAMOND_ORE, ChatColor.AQUA);
MATERIAL_COLORS.put(Material.EMERALD_ORE, ChatColor.GREEN);
MATERIAL_COLORS.put(Material.ANCIENT_DEBRIS, ChatColor.DARK_RED);
if (Prerequisite.HAS_1_17.isMet()) {
MATERIAL_COLORS.put(Material.COPPER_ORE, ChatColor.GOLD);
MATERIAL_COLORS.put(Material.DEEPSLATE_COPPER_ORE, ChatColor.GOLD);
MATERIAL_COLORS.put(Material.DEEPSLATE_COAL_ORE, ChatColor.BLACK);
MATERIAL_COLORS.put(Material.DEEPSLATE_IRON_ORE, ChatColor.GRAY);
MATERIAL_COLORS.put(Material.DEEPSLATE_GOLD_ORE, ChatColor.YELLOW);
MATERIAL_COLORS.put(Material.DEEPSLATE_LAPIS_ORE, ChatColor.BLUE);
MATERIAL_COLORS.put(Material.DEEPSLATE_REDSTONE_ORE, ChatColor.RED);
MATERIAL_COLORS.put(Material.DEEPSLATE_DIAMOND_ORE, ChatColor.AQUA);
MATERIAL_COLORS.put(Material.DEEPSLATE_EMERALD_ORE, ChatColor.GREEN);
}
}
}

View File

@@ -22,11 +22,10 @@ import java.util.Arrays;
public final class ChatComponent implements ChatComponentProxy {
@Override
public Object modifyComponent(@NotNull final Object object) {
if (!(object instanceof IChatBaseComponent)) {
if (!(object instanceof IChatBaseComponent chatComponent)) {
return object;
}
IChatBaseComponent chatComponent = (IChatBaseComponent) object;
for (IChatBaseComponent iChatBaseComponent : chatComponent) {
if (iChatBaseComponent == null) {
continue;

View File

@@ -22,11 +22,10 @@ import java.util.Arrays;
public final class ChatComponent implements ChatComponentProxy {
@Override
public Object modifyComponent(@NotNull final Object object) {
if (!(object instanceof IChatBaseComponent)) {
if (!(object instanceof IChatBaseComponent chatComponent)) {
return object;
}
IChatBaseComponent chatComponent = (IChatBaseComponent) object;
for (IChatBaseComponent iChatBaseComponent : chatComponent) {
if (iChatBaseComponent == null) {
continue;

View File

@@ -22,11 +22,10 @@ import java.util.Arrays;
public final class ChatComponent implements ChatComponentProxy {
@Override
public Object modifyComponent(@NotNull final Object object) {
if (!(object instanceof IChatBaseComponent)) {
if (!(object instanceof IChatBaseComponent chatComponent)) {
return object;
}
IChatBaseComponent chatComponent = (IChatBaseComponent) object;
for (IChatBaseComponent iChatBaseComponent : chatComponent) {
if (iChatBaseComponent == null) {
continue;

View File

@@ -22,11 +22,10 @@ import java.util.Arrays;
public final class ChatComponent implements ChatComponentProxy {
@Override
public Object modifyComponent(@NotNull final Object object) {
if (!(object instanceof IChatBaseComponent)) {
if (!(object instanceof IChatBaseComponent chatComponent)) {
return object;
}
IChatBaseComponent chatComponent = (IChatBaseComponent) object;
for (IChatBaseComponent iChatBaseComponent : chatComponent) {
if (iChatBaseComponent == null) {
continue;

View File

@@ -4,6 +4,7 @@ version rootProject.version
dependencies {
implementation 'org.apache.maven:maven-artifact:3.0.3'
implementation 'org.bstats:bstats-bukkit:1.7'
implementation 'com.google.code.gson:gson:2.8.7'
compileOnly 'org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT'
compileOnly project(":eco-core:core-proxy")
compileOnly 'com.comphenix.protocol:ProtocolLib:4.6.0-SNAPSHOT'

View File

@@ -3,6 +3,7 @@ package com.willfp.eco.spigot;
import com.willfp.eco.core.AbstractPacketAdapter;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.command.AbstractCommand;
import com.willfp.eco.core.config.base.LangYml;
import com.willfp.eco.core.data.Data;
import com.willfp.eco.core.display.Display;
import com.willfp.eco.core.display.DisplayModule;
@@ -10,10 +11,11 @@ import com.willfp.eco.core.integrations.IntegrationLoader;
import com.willfp.eco.core.integrations.anticheat.AnticheatManager;
import com.willfp.eco.core.integrations.antigrief.AntigriefManager;
import com.willfp.eco.core.integrations.mcmmo.McmmoManager;
import com.willfp.eco.internal.InternalInterfacing;
import com.willfp.eco.proxy.proxies.BlockBreakProxy;
import com.willfp.eco.proxy.proxies.SkullProxy;
import com.willfp.eco.proxy.proxies.TridentStackProxy;
import com.willfp.eco.spigot.config.DataYml;
import com.willfp.eco.spigot.config.DataJson;
import com.willfp.eco.spigot.display.PacketAutoRecipe;
import com.willfp.eco.spigot.display.PacketChat;
import com.willfp.eco.spigot.display.PacketOpenWindowMerchant;
@@ -25,8 +27,13 @@ import com.willfp.eco.spigot.eventlisteners.ArmorListener;
import com.willfp.eco.spigot.eventlisteners.DispenserArmorListener;
import com.willfp.eco.spigot.eventlisteners.EntityDeathByEntityListeners;
import com.willfp.eco.spigot.eventlisteners.NaturalExpGainListeners;
import com.willfp.eco.spigot.eventlisteners.PlayerJumpListeners;
import com.willfp.eco.spigot.gui.GUIListener;
import com.willfp.eco.spigot.integrations.anticheat.*;
import com.willfp.eco.spigot.integrations.anticheat.AnticheatAAC;
import com.willfp.eco.spigot.integrations.anticheat.AnticheatMatrix;
import com.willfp.eco.spigot.integrations.anticheat.AnticheatNCP;
import com.willfp.eco.spigot.integrations.anticheat.AnticheatSpartan;
import com.willfp.eco.spigot.integrations.anticheat.AnticheatVulcan;
import com.willfp.eco.spigot.integrations.antigrief.AntigriefCombatLogX;
import com.willfp.eco.spigot.integrations.antigrief.AntigriefFactionsUUID;
import com.willfp.eco.spigot.integrations.antigrief.AntigriefGriefPrevention;
@@ -56,9 +63,9 @@ public class EcoSpigotPlugin extends EcoPlugin {
private static EcoSpigotPlugin instance;
/**
* data.yml.
* data.json.
*/
private final DataYml dataYml;
private final DataJson dataJson;
/**
* Create a new instance of eco.
@@ -77,8 +84,15 @@ public class EcoSpigotPlugin extends EcoPlugin {
TridentStackProxy tridentStackProxy = InternalProxyUtils.getProxy(TridentStackProxy.class);
TridentUtils.initialize(tridentStackProxy::getTridentStack);
this.dataYml = new DataYml(this);
Data.init(this.dataYml);
this.dataJson = new DataJson(this);
Data.init(this.dataJson);
InternalInterfacing.setInterfacing(new InternalInterfacing() {
@Override
public LangYml getLang() {
return EcoSpigotPlugin.getInstance().getLangYml();
}
});
}
@Override
@@ -89,7 +103,7 @@ public class EcoSpigotPlugin extends EcoPlugin {
@Override
public void disable() {
try {
Data.save(this.dataYml);
Data.save(this.dataJson);
} catch (IOException e) {
e.printStackTrace();
}
@@ -163,7 +177,8 @@ public class EcoSpigotPlugin extends EcoPlugin {
new ArmorListener(),
new DispenserArmorListener(),
new EntityDeathByEntityListeners(this),
new ShapedRecipeListener(),
new ShapedRecipeListener(this),
new PlayerJumpListeners(),
new GUIListener(this)
);
}

View File

@@ -0,0 +1,16 @@
package com.willfp.eco.spigot.config;
import com.willfp.eco.core.config.JsonStaticBaseConfig;
import com.willfp.eco.spigot.EcoSpigotPlugin;
import org.jetbrains.annotations.NotNull;
public class DataJson extends JsonStaticBaseConfig {
/**
* Init data.json.
*
* @param plugin EcoSpigotPlugin.
*/
public DataJson(@NotNull final EcoSpigotPlugin plugin) {
super("data", plugin);
}
}

View File

@@ -1,16 +0,0 @@
package com.willfp.eco.spigot.config;
import com.willfp.eco.core.config.BaseConfig;
import com.willfp.eco.spigot.EcoSpigotPlugin;
import org.jetbrains.annotations.NotNull;
public class DataYml extends BaseConfig {
/**
* Init data.yml.
*
* @param plugin EcoSpigotPlugin.
*/
public DataYml(@NotNull final EcoSpigotPlugin plugin) {
super("data", false, plugin);
}
}

View File

@@ -12,8 +12,7 @@ public class DispenserArmorListener implements Listener {
@EventHandler
public void dispenseArmorEvent(@NotNull final BlockDispenseArmorEvent event) {
ArmorType type = ArmorType.matchType(event.getItem());
if (type != null && event.getTargetEntity() instanceof Player) {
Player p = (Player) event.getTargetEntity();
if (type != null && event.getTargetEntity() instanceof Player p) {
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(p);
Bukkit.getPluginManager().callEvent(armorEquipEvent);
}

View File

@@ -41,12 +41,10 @@ public class EntityDeathByEntityListeners extends PluginDependent implements Lis
*/
@EventHandler(priority = EventPriority.HIGH)
public void onEntityDamage(@NotNull final EntityDamageByEntityEvent event) {
if (!(event.getEntity() instanceof LivingEntity)) {
if (!(event.getEntity() instanceof LivingEntity victim)) {
return;
}
LivingEntity victim = (LivingEntity) event.getEntity();
if (victim.getHealth() > event.getFinalDamage()) {
return;
}

View File

@@ -0,0 +1,62 @@
package com.willfp.eco.spigot.eventlisteners;
import com.willfp.eco.core.events.PlayerJumpEvent;
import com.willfp.eco.core.integrations.mcmmo.McmmoManager;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
import java.text.DecimalFormat;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
@SuppressWarnings("deprecation")
public class PlayerJumpListeners implements Listener {
/**
* For jump listeners.
*/
private static final Set<UUID> PREVIOUS_PLAYERS_ON_GROUND = new HashSet<>();
/**
* For jump listeners.
*/
private static final DecimalFormat FORMAT = new DecimalFormat("0.00");
/**
* Called when a player jumps.
*
* @param event The event to listen for.
*/
@EventHandler(ignoreCancelled = true)
public void onJump(@NotNull final PlayerMoveEvent event) {
if (McmmoManager.isFake(event)) {
return;
}
Player player = event.getPlayer();
if (player.getVelocity().getY() > 0) {
float jumpVelocity = 0.42f;
if (player.hasPotionEffect(PotionEffectType.JUMP)) {
jumpVelocity += ((float) player.getPotionEffect(PotionEffectType.JUMP).getAmplifier() + 1) * 0.1F;
}
jumpVelocity = Float.parseFloat(FORMAT.format(jumpVelocity).replace(',', '.'));
if (event.getPlayer().getLocation().getBlock().getType() != Material.LADDER
&& PREVIOUS_PLAYERS_ON_GROUND.contains(player.getUniqueId())
&& !player.isOnGround()
&& Float.compare((float) player.getVelocity().getY(), jumpVelocity) == 0) {
Bukkit.getPluginManager().callEvent(new PlayerJumpEvent(event));
}
}
if (player.isOnGround()) {
PREVIOUS_PLAYERS_ON_GROUND.add(player.getUniqueId());
} else {
PREVIOUS_PLAYERS_ON_GROUND.remove(player.getUniqueId());
}
}
}

View File

@@ -2,20 +2,15 @@ package com.willfp.eco.spigot.gui;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginDependent;
import com.willfp.eco.core.gui.menu.FillerMask;
import com.willfp.eco.core.gui.menu.Menu;
import com.willfp.eco.core.gui.slot.Slot;
import com.willfp.eco.internal.gui.EcoMenu;
import com.willfp.eco.internal.gui.EcoSlot;
import com.willfp.eco.internal.gui.MenuHandler;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
public class GUIListener extends PluginDependent implements Listener {
@@ -65,31 +60,4 @@ public class GUIListener extends PluginDependent implements Listener {
this.getPlugin().getScheduler().run(() -> MenuHandler.unregisterMenu(event.getInventory()));
}
@EventHandler
public void test(@NotNull final AsyncPlayerChatEvent event) {
String message = event.getMessage();
if (!message.equals("guitest")) {
return;
}
this.getPlugin().getScheduler().run(() -> {
Menu.builder(5)
.setMask(new FillerMask(
Material.BLACK_STAINED_GLASS_PANE,
"111111111",
"100000001",
"100000001",
"100000001",
"111111111"
))
.setSlot(1, 3, Slot.builder(new ItemStack(Material.TNT))
.onLeftClick((event1, slot) -> event1.getWhoClicked().sendMessage("CLICK"))
.build())
.setTitle("Poggers")
.onClose(event1 -> event1.getPlayer().sendMessage("CLOSED"))
.build()
.open(event.getPlayer());
});
}
}

View File

@@ -1,15 +1,18 @@
package com.willfp.eco.spigot.recipes;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginDependent;
import com.willfp.eco.core.items.Items;
import com.willfp.eco.core.items.TestableItem;
import com.willfp.eco.core.recipe.Recipes;
import com.willfp.eco.core.recipe.parts.MaterialTestableItem;
import com.willfp.eco.core.recipe.parts.TestableStack;
import com.willfp.eco.core.recipe.recipes.CraftingRecipe;
import com.willfp.eco.core.recipe.recipes.ShapedCraftingRecipe;
import org.bukkit.Material;
import org.bukkit.event.Event;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.CraftItemEvent;
import org.bukkit.event.inventory.PrepareItemCraftEvent;
@@ -18,7 +21,16 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.ShapedRecipe;
import org.jetbrains.annotations.NotNull;
public class ShapedRecipeListener implements Listener {
public class ShapedRecipeListener extends PluginDependent implements Listener {
/**
* Pass an {@link EcoPlugin} in order to interface with it.
*
* @param plugin The plugin to manage.
*/
public ShapedRecipeListener(@NotNull final EcoPlugin plugin) {
super(plugin);
}
/**
* Called on item craft.
*
@@ -26,12 +38,10 @@ public class ShapedRecipeListener implements Listener {
*/
@EventHandler
public void complexRecipeListener(@NotNull final PrepareItemCraftEvent event) {
if (!(event.getRecipe() instanceof ShapedRecipe)) {
if (!(event.getRecipe() instanceof ShapedRecipe recipe)) {
return;
}
ShapedRecipe recipe = (ShapedRecipe) event.getRecipe();
if (!EcoPlugin.LOADED_ECO_PLUGINS.contains(recipe.getKey().getNamespace())) {
return;
}
@@ -58,12 +68,10 @@ public class ShapedRecipeListener implements Listener {
*/
@EventHandler
public void complexRecipeListener(@NotNull final CraftItemEvent event) {
if (!(event.getRecipe() instanceof ShapedRecipe)) {
if (!(event.getRecipe() instanceof ShapedRecipe recipe)) {
return;
}
ShapedRecipe recipe = (ShapedRecipe) event.getRecipe();
if (!EcoPlugin.LOADED_ECO_PLUGINS.contains(recipe.getKey().getNamespace())) {
return;
}
@@ -92,22 +100,52 @@ public class ShapedRecipeListener implements Listener {
*
* @param event The event to listen for.
*/
@EventHandler
public void preventUsingComplexPartInEcoRecipe(@NotNull final PrepareItemCraftEvent event) {
if (!(event.getRecipe() instanceof ShapedRecipe)) {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void stackedRecipeListener(@NotNull final CraftItemEvent event) {
if (!(event.getRecipe() instanceof ShapedRecipe recipe)) {
return;
}
ShapedRecipe recipe = (ShapedRecipe) event.getRecipe();
if (!EcoPlugin.LOADED_ECO_PLUGINS.contains(recipe.getKey().getNamespace())) {
return;
}
ItemStack[] matrix = event.getInventory().getMatrix();
CraftingRecipe matched = Recipes.getMatch(matrix);
if (matched == null) {
return;
}
this.getPlugin().getScheduler().runLater(() -> {
for (int i = 0; i < 9; i++) {
ItemStack inMatrix = event.getInventory().getMatrix()[i];
TestableItem inRecipe = matched.getParts().get(i);
if (inRecipe instanceof TestableStack testableStack) {
inMatrix.setAmount(inMatrix.getAmount() - (testableStack.getAmount() - 1));
}
}
}, 1);
}
/**
* Called on item craft.
*
* @param event The event to listen for.
*/
@EventHandler
public void preventUsingComplexPartInEcoRecipe(@NotNull final PrepareItemCraftEvent event) {
if (!(event.getRecipe() instanceof ShapedRecipe recipe)) {
return;
}
CraftingRecipe craftingRecipe = Recipes.getRecipe(recipe.getKey());
if (!(craftingRecipe instanceof ShapedCraftingRecipe)) {
if (!(craftingRecipe instanceof ShapedCraftingRecipe shapedCraftingRecipe)) {
return;
}
ShapedCraftingRecipe shapedCraftingRecipe = (ShapedCraftingRecipe) craftingRecipe;
for (int i = 0; i < 9; i++) {
ItemStack itemStack = event.getInventory().getMatrix()[i];
TestableItem part = shapedCraftingRecipe.getParts().get(i);
@@ -127,20 +165,16 @@ public class ShapedRecipeListener implements Listener {
*/
@EventHandler
public void preventUsingComplexPartInEcoRecipe(@NotNull final CraftItemEvent event) {
if (!(event.getRecipe() instanceof ShapedRecipe)) {
if (!(event.getRecipe() instanceof ShapedRecipe recipe)) {
return;
}
ShapedRecipe recipe = (ShapedRecipe) event.getRecipe();
CraftingRecipe craftingRecipe = Recipes.getRecipe(recipe.getKey());
if (!(craftingRecipe instanceof ShapedCraftingRecipe)) {
if (!(craftingRecipe instanceof ShapedCraftingRecipe shapedCraftingRecipe)) {
return;
}
ShapedCraftingRecipe shapedCraftingRecipe = (ShapedCraftingRecipe) craftingRecipe;
for (int i = 0; i < 9; i++) {
ItemStack itemStack = event.getInventory().getMatrix()[i];
TestableItem part = shapedCraftingRecipe.getParts().get(i);
@@ -162,12 +196,10 @@ public class ShapedRecipeListener implements Listener {
*/
@EventHandler
public void preventUsingComplexPartInVanillaRecipe(@NotNull final PrepareItemCraftEvent event) {
if (!(event.getRecipe() instanceof ShapedRecipe)) {
if (!(event.getRecipe() instanceof ShapedRecipe recipe)) {
return;
}
ShapedRecipe recipe = (ShapedRecipe) event.getRecipe();
if (EcoPlugin.LOADED_ECO_PLUGINS.contains(recipe.getKey().getNamespace())) {
return;
}
@@ -187,12 +219,10 @@ public class ShapedRecipeListener implements Listener {
*/
@EventHandler
public void preventUsingComplexPartInVanillaRecipe(@NotNull final CraftItemEvent event) {
if (!(event.getRecipe() instanceof ShapedRecipe)) {
if (!(event.getRecipe() instanceof ShapedRecipe recipe)) {
return;
}
ShapedRecipe recipe = (ShapedRecipe) event.getRecipe();
if (EcoPlugin.LOADED_ECO_PLUGINS.contains(recipe.getKey().getNamespace())) {
return;
}

View File

@@ -0,0 +1,3 @@
{
}

View File

@@ -0,0 +1 @@
multiple-in-craft: '&l&c! &fThis recipe requires &a%amount%&f of this item.'

View File

@@ -1,2 +1,2 @@
version = 5.4.1
version = 5.5.0
plugin-name = eco