Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
007a579f5a | ||
|
|
9b19cd412a | ||
|
|
08b5cc1612 | ||
|
|
47aa61c7b3 | ||
|
|
ef1ee84358 | ||
|
|
49a36a4e81 | ||
|
|
bf76dec28e | ||
|
|
a0f51d79e8 | ||
|
|
9be516e511 | ||
|
|
a130935c62 | ||
|
|
4359bd17ae | ||
|
|
07726959e9 | ||
|
|
13c8187b3b | ||
|
|
be1267ef0c | ||
|
|
e61e9bc0a8 | ||
|
|
ec801cd776 | ||
|
|
a5b5bc6b46 | ||
|
|
f5efb50d71 | ||
|
|
d65c04aaa7 | ||
|
|
aa69d2a1a9 | ||
|
|
685cd5f998 | ||
|
|
bae4b567c8 | ||
|
|
0eb3315d61 | ||
|
|
0a42320b78 | ||
|
|
6ce0de8db7 | ||
|
|
345d4cd1b5 | ||
|
|
950c092025 | ||
|
|
0c6bb8c1b7 | ||
|
|
0f9cb7db7a | ||
|
|
7d4262e0ef | ||
|
|
e543be7a13 | ||
|
|
3d7027bf47 | ||
|
|
632b42ad65 | ||
|
|
bcd79e3886 | ||
|
|
8fbcf485b3 | ||
|
|
6a64be2e25 | ||
|
|
3f9f3991d8 | ||
|
|
54a8d942fa | ||
|
|
6aa14be577 | ||
|
|
d6db7673d8 | ||
|
|
d002073124 | ||
|
|
4bc98cae81 | ||
|
|
2696baf1d6 | ||
|
|
3c3cc36403 |
@@ -96,4 +96,4 @@ allprojects {
|
||||
group = 'com.willfp'
|
||||
archivesBaseName = project.name
|
||||
version = findProperty("version")
|
||||
java.sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
java.sourceCompatibility = JavaVersion.VERSION_16
|
||||
@@ -8,6 +8,8 @@
|
||||
<!-- Internals don't need javadoc. -->
|
||||
<suppress files="[\\/]internal[\\/]" checks="MissingJavadocMethod"/>
|
||||
<suppress files="[\\/]internal[\\/]" checks="JavadocVariable"/>
|
||||
<suppress files="[\\/]eco[\\/]spigot[\\/]" checks="MissingJavadocMethod"/>
|
||||
<suppress files="[\\/]eco[\\/]spigot[\\/]" checks="JavadocVariable"/>
|
||||
|
||||
<!-- Modified version of library -->
|
||||
<suppress files="ArmorEquipEvent.java" checks="JavadocVariable"/>
|
||||
|
||||
@@ -78,6 +78,32 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
|
||||
// Empty rather than abstract as implementations don't need both
|
||||
}
|
||||
|
||||
/**
|
||||
* The code that should be executed once the packet has been received.
|
||||
*
|
||||
* @param packet The packet.
|
||||
* @param player The player.
|
||||
* @param event The event.
|
||||
*/
|
||||
public void onReceive(@NotNull final PacketContainer packet,
|
||||
@NotNull final Player player,
|
||||
@NotNull final PacketEvent event) {
|
||||
// Empty rather than abstract as implementations don't need both
|
||||
}
|
||||
|
||||
/**
|
||||
* THe code that should be executed once the packet has been sent.
|
||||
*
|
||||
* @param packet The packet.
|
||||
* @param player The player.
|
||||
* @param event The event.
|
||||
*/
|
||||
public void onSend(@NotNull final PacketContainer packet,
|
||||
@NotNull final Player player,
|
||||
@NotNull final PacketEvent event) {
|
||||
// Empty rather than abstract as implementations don't need both
|
||||
}
|
||||
|
||||
/**
|
||||
* Boilerplate to assert that the packet is of the specified type.
|
||||
*
|
||||
@@ -94,6 +120,7 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
|
||||
}
|
||||
|
||||
onReceive(event.getPacket(), event.getPlayer());
|
||||
onReceive(event.getPacket(), event.getPlayer(), event);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -112,6 +139,7 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
|
||||
}
|
||||
|
||||
onSend(event.getPacket(), event.getPlayer());
|
||||
onSend(event.getPacket(), event.getPlayer(), event);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.willfp.eco.core;
|
||||
|
||||
import com.willfp.eco.core.proxy.ProxyConstants;
|
||||
import com.willfp.eco.util.ClassUtils;
|
||||
import lombok.Getter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -14,6 +15,7 @@ public class Prerequisite {
|
||||
* All existing prerequisites are registered on creation.
|
||||
*/
|
||||
private static final List<Prerequisite> VALUES = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Requires the server to be running an implementation of paper.
|
||||
*/
|
||||
@@ -22,6 +24,14 @@ public class Prerequisite {
|
||||
"Requires server to be running paper (or a fork)"
|
||||
);
|
||||
|
||||
/**
|
||||
* Requires the server to be running 1.17
|
||||
*/
|
||||
public static final Prerequisite v1_17 = new Prerequisite(
|
||||
() -> ProxyConstants.NMS_VERSION.contains("17"),
|
||||
"Requires server to be running 1.17+"
|
||||
);
|
||||
|
||||
/**
|
||||
* If the necessary prerequisite condition has been met.
|
||||
*/
|
||||
|
||||
142
eco-api/src/main/java/com/willfp/eco/core/data/Data.java
Normal file
142
eco-api/src/main/java/com/willfp/eco/core/data/Data.java
Normal file
@@ -0,0 +1,142 @@
|
||||
package com.willfp.eco.core.data;
|
||||
|
||||
import com.willfp.eco.core.config.BaseConfig;
|
||||
import com.willfp.eco.core.config.Config;
|
||||
import com.willfp.eco.internal.config.ConfigSection;
|
||||
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;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@UtilityClass
|
||||
public class Data {
|
||||
/**
|
||||
* Instance of eco data.yml.
|
||||
*/
|
||||
private static BaseConfig dataYml = null;
|
||||
|
||||
/**
|
||||
* All cached player data.
|
||||
*/
|
||||
private static final Map<UUID, Config> PLAYER_DATA = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Write an integer to a player's data.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public void init(@NotNull final BaseConfig config) {
|
||||
dataYml = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save to data.yml.
|
||||
*
|
||||
* @param config Instance of data.yml.
|
||||
* @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));
|
||||
}
|
||||
}
|
||||
config.save();
|
||||
}
|
||||
|
||||
private Config getPlayerConfig(@NotNull final OfflinePlayer player) {
|
||||
Config config = PLAYER_DATA.get(player.getUniqueId());
|
||||
|
||||
if (config == null) {
|
||||
config = dataYml.getSubsectionOrNull("player-data." + player.getUniqueId());
|
||||
if (config == null) {
|
||||
config = new ConfigSection(new YamlConfiguration());
|
||||
}
|
||||
PLAYER_DATA.put(player.getUniqueId(), config);
|
||||
return getPlayerConfig(player);
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.willfp.eco.core.gui.menu;
|
||||
|
||||
import com.willfp.eco.core.gui.slot.Slot;
|
||||
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 {
|
||||
@Getter
|
||||
private final List<List<Slot>> mask;
|
||||
|
||||
public FillerMask(@NotNull final Material material,
|
||||
@NotNull final String... pattern) {
|
||||
if (material == Material.AIR) {
|
||||
throw new IllegalArgumentException("Material cannot be air!");
|
||||
}
|
||||
|
||||
mask = ListUtils.create2DList(6, 9);
|
||||
|
||||
ItemStack itemStack = new ItemStack(material);
|
||||
ItemMeta meta = itemStack.getItemMeta();
|
||||
assert meta != null;
|
||||
meta.setDisplayName("§r");
|
||||
itemStack.setItemMeta(meta);
|
||||
|
||||
int row = 0;
|
||||
|
||||
for (String patternRow : pattern) {
|
||||
int column = 0;
|
||||
if (patternRow.length() != 9) {
|
||||
throw new IllegalArgumentException("Invalid amount of columns in pattern!");
|
||||
}
|
||||
for (char c : patternRow.toCharArray()) {
|
||||
if (c == '0') {
|
||||
mask.get(row).set(column, null);
|
||||
} else if (c == '1') {
|
||||
mask.get(row).set(column, new FillerSlot(itemStack));
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid character in pattern! (Must only be 0 and 1)");
|
||||
}
|
||||
|
||||
column++;
|
||||
}
|
||||
row++;
|
||||
}
|
||||
}
|
||||
}
|
||||
98
eco-api/src/main/java/com/willfp/eco/core/gui/menu/Menu.java
Normal file
98
eco-api/src/main/java/com/willfp/eco/core/gui/menu/Menu.java
Normal file
@@ -0,0 +1,98 @@
|
||||
package com.willfp.eco.core.gui.menu;
|
||||
|
||||
import com.willfp.eco.core.gui.slot.Slot;
|
||||
import com.willfp.eco.internal.gui.EcoMenu;
|
||||
import com.willfp.eco.internal.gui.FillerSlot;
|
||||
import com.willfp.eco.util.ListUtils;
|
||||
import com.willfp.eco.util.StringUtils;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public interface Menu {
|
||||
int getRows();
|
||||
|
||||
Slot getSlot(int row,
|
||||
int column);
|
||||
|
||||
String getTitle();
|
||||
|
||||
Inventory open(@NotNull Player player);
|
||||
|
||||
static Builder builder(final int rows) {
|
||||
return new Builder(rows);
|
||||
}
|
||||
|
||||
class Builder {
|
||||
private final int rows;
|
||||
private String title = "Menu";
|
||||
private List<List<Slot>> maskSlots;
|
||||
private final List<List<Slot>> slots;
|
||||
private Consumer<InventoryCloseEvent> onClose = (event) -> {
|
||||
};
|
||||
|
||||
Builder(final int rows) {
|
||||
this.rows = rows;
|
||||
this.slots = ListUtils.create2DList(rows, 9);
|
||||
this.maskSlots = ListUtils.create2DList(rows, 9);
|
||||
}
|
||||
|
||||
public Builder setTitle(@NotNull final String title) {
|
||||
this.title = StringUtils.translate(title);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setSlot(final int row,
|
||||
final int column,
|
||||
@NotNull final Slot slot) {
|
||||
if (row < 1 || row > this.rows) {
|
||||
throw new IllegalArgumentException("Invalid row number!");
|
||||
}
|
||||
|
||||
if (column < 1 || column > 9) {
|
||||
throw new IllegalArgumentException("Invalid column number!");
|
||||
}
|
||||
|
||||
slots.get(row - 1).set(column - 1, slot);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setMask(@NotNull final FillerMask mask) {
|
||||
this.maskSlots = mask.getMask();
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder onClose(@NotNull final Consumer<InventoryCloseEvent> action) {
|
||||
this.onClose = action;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Menu build() {
|
||||
List<List<Slot>> finalSlots = maskSlots;
|
||||
for (int i = 0; i < slots.size(); i++) {
|
||||
for (int j = 0; j < slots.get(i).size(); j++) {
|
||||
Slot slot = slots.get(i).get(j);
|
||||
if (slot != null) {
|
||||
finalSlots.get(i).set(j, slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (List<Slot> finalSlot : finalSlots) {
|
||||
for (int j = 0; j < finalSlot.size(); j++) {
|
||||
if (finalSlot.get(j) == null) {
|
||||
finalSlot.set(j, new FillerSlot(new ItemStack(Material.AIR)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new EcoMenu(rows, finalSlots, title, onClose);
|
||||
}
|
||||
}
|
||||
}
|
||||
63
eco-api/src/main/java/com/willfp/eco/core/gui/slot/Slot.java
Normal file
63
eco-api/src/main/java/com/willfp/eco/core/gui/slot/Slot.java
Normal file
@@ -0,0 +1,63 @@
|
||||
package com.willfp.eco.core.gui.slot;
|
||||
|
||||
import com.willfp.eco.internal.gui.EcoSlot;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public interface Slot {
|
||||
ItemStack getItemStack();
|
||||
|
||||
static Builder builder(@NotNull final ItemStack itemStack) {
|
||||
return new Builder(itemStack);
|
||||
}
|
||||
|
||||
class Builder {
|
||||
private final ItemStack itemStack;
|
||||
|
||||
private BiConsumer<InventoryClickEvent, Slot> onLeftClick = null;
|
||||
|
||||
private BiConsumer<InventoryClickEvent, Slot> onRightClick = null;
|
||||
|
||||
private BiConsumer<InventoryClickEvent, Slot> onShiftLeftClick = null;
|
||||
|
||||
private BiConsumer<InventoryClickEvent, Slot> onShiftRightClick = null;
|
||||
|
||||
private BiConsumer<InventoryClickEvent, Slot> onMiddleClick = null;
|
||||
|
||||
Builder(@NotNull final ItemStack itemStack) {
|
||||
this.itemStack = itemStack;
|
||||
}
|
||||
|
||||
public Builder onLeftClick(@NotNull final BiConsumer<InventoryClickEvent, Slot> action) {
|
||||
this.onLeftClick = action;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder onRightClick(@NotNull final BiConsumer<InventoryClickEvent, Slot> action) {
|
||||
this.onRightClick = action;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder onShiftLeftClick(@NotNull final BiConsumer<InventoryClickEvent, Slot> action) {
|
||||
this.onShiftLeftClick = action;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder onShiftRightClick(@NotNull final BiConsumer<InventoryClickEvent, Slot> action) {
|
||||
this.onShiftRightClick = action;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder onMiddleClick(@NotNull final BiConsumer<InventoryClickEvent, Slot> action) {
|
||||
this.onMiddleClick = action;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Slot build() {
|
||||
return new EcoSlot(itemStack, onLeftClick, onRightClick, onShiftLeftClick, onShiftRightClick, onMiddleClick);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ public class ConfigSection extends ConfigWrapper<ConfigurationSection> {
|
||||
*
|
||||
* @param section The section.
|
||||
*/
|
||||
protected ConfigSection(@NotNull final ConfigurationSection section) {
|
||||
public ConfigSection(@NotNull final ConfigurationSection section) {
|
||||
this.init(section);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ public abstract class ConfigWrapper<T extends ConfigurationSection> implements C
|
||||
@Override
|
||||
public void set(@NotNull final String path,
|
||||
@Nullable final Object object) {
|
||||
cache.remove(path);
|
||||
handle.set(path, object);
|
||||
}
|
||||
|
||||
@@ -81,7 +82,12 @@ public abstract class ConfigWrapper<T extends ConfigurationSection> implements C
|
||||
if (cache.containsKey(path)) {
|
||||
return (Config) cache.get(path);
|
||||
} else {
|
||||
cache.put(path, new ConfigSection(Objects.requireNonNull(handle.getConfigurationSection(path))));
|
||||
ConfigurationSection raw = handle.getConfigurationSection(path);
|
||||
if (raw == null) {
|
||||
cache.put(path, null);
|
||||
} else {
|
||||
cache.put(path, new ConfigSection(raw));
|
||||
}
|
||||
return getSubsectionOrNull(path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.willfp.eco.internal.gui;
|
||||
|
||||
import com.willfp.eco.core.gui.menu.Menu;
|
||||
import com.willfp.eco.core.gui.slot.Slot;
|
||||
import com.willfp.eco.util.StringUtils;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class EcoMenu implements Menu {
|
||||
@Getter
|
||||
private final int rows;
|
||||
|
||||
private final List<List<Slot>> slots;
|
||||
|
||||
@Getter
|
||||
private final String title;
|
||||
|
||||
private final Consumer<InventoryCloseEvent> onClose;
|
||||
|
||||
public EcoMenu(final int rows,
|
||||
@NotNull final List<List<Slot>> slots,
|
||||
@NotNull final String title,
|
||||
@NotNull final Consumer<InventoryCloseEvent> onClose) {
|
||||
this.rows = rows;
|
||||
this.slots = slots;
|
||||
this.title = title;
|
||||
this.onClose = onClose;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Slot getSlot(final int row,
|
||||
final int column) {
|
||||
if (row < 1 || row > this.rows) {
|
||||
throw new IllegalArgumentException("Invalid row number!");
|
||||
}
|
||||
|
||||
if (column < 1 || column > 9) {
|
||||
throw new IllegalArgumentException("Invalid column number!");
|
||||
}
|
||||
|
||||
return slots.get(row - 1).get(column - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Inventory open(@NotNull final Player player) {
|
||||
Inventory inventory = Bukkit.createInventory(null, rows * 9, title);
|
||||
int i = 0;
|
||||
for (List<Slot> row : slots) {
|
||||
for (Slot item : row) {
|
||||
if (i == rows * 9) {
|
||||
break;
|
||||
}
|
||||
ItemStack slotItem = item.getItemStack();
|
||||
ItemMeta meta = slotItem.getItemMeta();
|
||||
if (meta != null) {
|
||||
List<String> lore = meta.getLore();
|
||||
if (lore != null) {
|
||||
lore.replaceAll(s -> StringUtils.translate(s, player));
|
||||
meta.setLore(lore);
|
||||
}
|
||||
slotItem.setItemMeta(meta);
|
||||
}
|
||||
inventory.setItem(i, slotItem);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
player.openInventory(inventory);
|
||||
MenuHandler.registerMenu(inventory, this);
|
||||
return inventory;
|
||||
}
|
||||
|
||||
public void handleClose(@NotNull final InventoryCloseEvent event) {
|
||||
onClose.accept(event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.willfp.eco.internal.gui;
|
||||
|
||||
import com.willfp.eco.core.gui.slot.Slot;
|
||||
import lombok.Getter;
|
||||
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;
|
||||
|
||||
public class EcoSlot implements Slot {
|
||||
@Getter
|
||||
private final ItemStack itemStack;
|
||||
|
||||
private final BiConsumer<InventoryClickEvent, Slot> onLeftClick;
|
||||
|
||||
private final BiConsumer<InventoryClickEvent, Slot> onRightClick;
|
||||
|
||||
private final BiConsumer<InventoryClickEvent, Slot> onShiftLeftClick;
|
||||
|
||||
private final BiConsumer<InventoryClickEvent, Slot> onShiftRightClick;
|
||||
|
||||
private final BiConsumer<InventoryClickEvent, Slot> onMiddleClick;
|
||||
|
||||
public EcoSlot(@NotNull final ItemStack itemStack,
|
||||
@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.onLeftClick = onLeftClick == null ? ((event, slot) -> { }) : onLeftClick;
|
||||
this.onRightClick = onRightClick == null ? ((event, slot) -> { }) : onRightClick;
|
||||
this.onShiftLeftClick = onShiftLeftClick == null ? ((event, slot) -> { }) : onShiftLeftClick;
|
||||
this.onShiftRightClick = onShiftRightClick == null ? ((event, slot) -> { }) : onShiftRightClick;
|
||||
this.onMiddleClick = onMiddleClick == null ? ((event, slot) -> { }) : onMiddleClick;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.willfp.eco.internal.gui;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class FillerSlot extends EcoSlot {
|
||||
/**
|
||||
* Create new filler slot.
|
||||
*
|
||||
* @param itemStack The ItemStack.
|
||||
*/
|
||||
public FillerSlot(@NotNull final ItemStack itemStack) {
|
||||
super(itemStack, null, null, null, null, null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.willfp.eco.internal.gui;
|
||||
|
||||
import com.willfp.eco.core.gui.menu.Menu;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@UtilityClass
|
||||
public class MenuHandler {
|
||||
private static final Map<Inventory, Menu> MENUS = new HashMap<>();
|
||||
|
||||
public void registerMenu(@NotNull final Inventory inventory,
|
||||
@NotNull final Menu menu) {
|
||||
MENUS.put(inventory, menu);
|
||||
}
|
||||
|
||||
public void unregisterMenu(@NotNull final Inventory inventory) {
|
||||
MENUS.remove(inventory);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Menu getMenu(@NotNull final Inventory inventory) {
|
||||
return MENUS.get(inventory);
|
||||
}
|
||||
}
|
||||
@@ -37,15 +37,6 @@ public class BlockUtils {
|
||||
if (blocks.size() > limit || blocks.size() > 2500) {
|
||||
return blocks;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Running twice to get more spherical shape.
|
||||
for (BlockFace face : BlockFace.values()) {
|
||||
Block block = start.getRelative(face);
|
||||
if (!blocks.contains(block) && allowedMaterials.contains(block.getType())) {
|
||||
if (blocks.size() > limit || blocks.size() > 2500) {
|
||||
return blocks;
|
||||
}
|
||||
blocks.addAll(getNearbyBlocks(block, allowedMaterials, blocks, limit));
|
||||
}
|
||||
}
|
||||
|
||||
31
eco-api/src/main/java/com/willfp/eco/util/ListUtils.java
Normal file
31
eco-api/src/main/java/com/willfp/eco/util/ListUtils.java
Normal file
@@ -0,0 +1,31 @@
|
||||
package com.willfp.eco.util;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@UtilityClass
|
||||
public class ListUtils {
|
||||
/**
|
||||
* Initialize 2D list of a given size.
|
||||
*
|
||||
* @param rows The amount of rows.
|
||||
* @param columns The amount of columns.
|
||||
* @param <T> The type of the object stored in the list.
|
||||
* @return The list, filled will null objects.
|
||||
*/
|
||||
public <T> List<List<T>> create2DList(final int rows,
|
||||
final int columns) {
|
||||
List<List<T>> list = new ArrayList<>(rows);
|
||||
while (list.size() < rows) {
|
||||
List<T> row = new ArrayList<>(columns);
|
||||
while (row.size() < columns) {
|
||||
row.add(null);
|
||||
}
|
||||
list.add(row);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@@ -10,20 +10,10 @@ import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
@UtilityClass
|
||||
public class NumberUtils {
|
||||
/**
|
||||
* Precision.
|
||||
*/
|
||||
private static final int FAST_TRIG_PRECISION = 100;
|
||||
|
||||
/**
|
||||
* Modulus.
|
||||
*/
|
||||
private static final int FAST_TRIG_MODULUS = 360 * FAST_TRIG_PRECISION;
|
||||
|
||||
/**
|
||||
* Sin lookup table.
|
||||
*/
|
||||
private static final double[] SIN_LOOKUP = new double[FAST_TRIG_MODULUS];
|
||||
private static final double[] SIN_LOOKUP = new double[65536];
|
||||
|
||||
/**
|
||||
* Set of roman numerals to look up.
|
||||
@@ -45,15 +35,11 @@ public class NumberUtils {
|
||||
NUMERALS.put(4, "IV");
|
||||
NUMERALS.put(1, "I");
|
||||
|
||||
for (int i = 0; i < SIN_LOOKUP.length; i++) {
|
||||
SIN_LOOKUP[i] = Math.sin((i * Math.PI) / (FAST_TRIG_PRECISION * 180));
|
||||
for (int i = 0; i < 65536; ++i) {
|
||||
SIN_LOOKUP[i] = Math.sin((double) i * 3.141592653589793D * 2.0D / 65536.0D);
|
||||
}
|
||||
}
|
||||
|
||||
private static double sinLookup(final int a) {
|
||||
return a >= 0 ? SIN_LOOKUP[a % FAST_TRIG_MODULUS] : -SIN_LOOKUP[-a % FAST_TRIG_MODULUS];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the sin of a number.
|
||||
*
|
||||
@@ -61,7 +47,8 @@ public class NumberUtils {
|
||||
* @return The sin.
|
||||
*/
|
||||
public static double fastSin(final double a) {
|
||||
return sinLookup((int) (a * FAST_TRIG_PRECISION + 0.5f));
|
||||
float f = (float) a;
|
||||
return SIN_LOOKUP[(int) (f * 10430.378F) & '\uffff'];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,7 +58,8 @@ public class NumberUtils {
|
||||
* @return The cosine.
|
||||
*/
|
||||
public static double fastCos(final double a) {
|
||||
return sinLookup((int) ((a + 90f) * FAST_TRIG_PRECISION + 0.5f));
|
||||
float f = (float) a;
|
||||
return SIN_LOOKUP[(int) (f * 10430.378F + 16384.0F) & '\uffff'];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -79,6 +79,7 @@ public class TeamUtils {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,13 +27,25 @@ public final class ChatComponent implements ChatComponentProxy {
|
||||
}
|
||||
|
||||
IChatBaseComponent chatComponent = (IChatBaseComponent) object;
|
||||
chatComponent.stream().forEach(this::modifyBaseComponent);
|
||||
for (IChatBaseComponent iChatBaseComponent : chatComponent) {
|
||||
if (iChatBaseComponent == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
modifyBaseComponent(iChatBaseComponent);
|
||||
}
|
||||
|
||||
return chatComponent;
|
||||
}
|
||||
|
||||
private void modifyBaseComponent(@NotNull final IChatBaseComponent component) {
|
||||
component.getSiblings().forEach(this::modifyBaseComponent);
|
||||
for (IChatBaseComponent sibling : component.getSiblings()) {
|
||||
if (sibling == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
modifyBaseComponent(sibling);
|
||||
}
|
||||
if (component instanceof ChatMessage) {
|
||||
Arrays.stream(((ChatMessage) component).getArgs())
|
||||
.filter(o -> o instanceof IChatBaseComponent)
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package com.willfp.eco.proxy.v1_16_R1;
|
||||
|
||||
import com.willfp.eco.proxy.proxies.VillagerTradeProxy;
|
||||
import com.willfp.eco.core.display.Display;
|
||||
import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftItemStack;
|
||||
import com.willfp.eco.proxy.proxies.VillagerTradeProxy;
|
||||
import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftMerchantRecipe;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.MerchantRecipe;
|
||||
@@ -11,30 +10,56 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public final class VillagerTrade implements VillagerTradeProxy {
|
||||
@Override
|
||||
public void displayTrade(@NotNull final MerchantRecipe merchantRecipe) {
|
||||
/**
|
||||
* Handle.
|
||||
*/
|
||||
private final Field handle;
|
||||
|
||||
/**
|
||||
* Create new Villager Trade.
|
||||
*/
|
||||
public VillagerTrade() {
|
||||
try {
|
||||
// Bukkit MerchantRecipe result
|
||||
Field fResult = MerchantRecipe.class.getDeclaredField("result");
|
||||
fResult.setAccessible(true);
|
||||
ItemStack result = merchantRecipe.getResult();
|
||||
Display.displayAndFinalize(result);
|
||||
fResult.set(merchantRecipe, result);
|
||||
|
||||
// Get NMS MerchantRecipe from CraftMerchantRecipe
|
||||
Field fHandle = CraftMerchantRecipe.class.getDeclaredField("handle");
|
||||
fHandle.setAccessible(true);
|
||||
net.minecraft.server.v1_16_R1.MerchantRecipe handle = (net.minecraft.server.v1_16_R1.MerchantRecipe) fHandle.get(merchantRecipe); // NMS Recipe
|
||||
|
||||
Field fSelling = net.minecraft.server.v1_16_R1.MerchantRecipe.class.getDeclaredField("sellingItem");
|
||||
fSelling.setAccessible(true);
|
||||
|
||||
ItemStack selling = CraftItemStack.asBukkitCopy(handle.sellingItem);
|
||||
Display.displayAndFinalize(selling);
|
||||
|
||||
fSelling.set(handle, CraftItemStack.asNMSCopy(selling));
|
||||
} catch (IllegalAccessException | NoSuchFieldException e) {
|
||||
handle = CraftMerchantRecipe.class.getDeclaredField("handle");
|
||||
handle.setAccessible(true);
|
||||
return;
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
throw new RuntimeException("Error!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public MerchantRecipe displayTrade(@NotNull final MerchantRecipe recipe) {
|
||||
CraftMerchantRecipe oldRecipe = (CraftMerchantRecipe) recipe;
|
||||
|
||||
CraftMerchantRecipe newRecipe = new CraftMerchantRecipe(
|
||||
Display.display(recipe.getResult().clone()),
|
||||
recipe.getUses(),
|
||||
recipe.getMaxUses(),
|
||||
recipe.hasExperienceReward(),
|
||||
recipe.getVillagerExperience(),
|
||||
recipe.getPriceMultiplier()
|
||||
);
|
||||
|
||||
for (ItemStack ingredient : recipe.getIngredients()) {
|
||||
newRecipe.addIngredient(Display.display(ingredient.clone()));
|
||||
}
|
||||
|
||||
getHandle(newRecipe).setSpecialPrice(getHandle(oldRecipe).getSpecialPrice());
|
||||
|
||||
return newRecipe;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private net.minecraft.server.v1_16_R1.MerchantRecipe getHandle(@NotNull final CraftMerchantRecipe recipe) {
|
||||
try {
|
||||
return (net.minecraft.server.v1_16_R1.MerchantRecipe) handle.get(recipe);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Not CMR");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,13 +27,25 @@ public final class ChatComponent implements ChatComponentProxy {
|
||||
}
|
||||
|
||||
IChatBaseComponent chatComponent = (IChatBaseComponent) object;
|
||||
chatComponent.stream().forEach(this::modifyBaseComponent);
|
||||
for (IChatBaseComponent iChatBaseComponent : chatComponent) {
|
||||
if (iChatBaseComponent == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
modifyBaseComponent(iChatBaseComponent);
|
||||
}
|
||||
|
||||
return chatComponent;
|
||||
}
|
||||
|
||||
private void modifyBaseComponent(@NotNull final IChatBaseComponent component) {
|
||||
component.getSiblings().forEach(this::modifyBaseComponent);
|
||||
for (IChatBaseComponent sibling : component.getSiblings()) {
|
||||
if (sibling == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
modifyBaseComponent(sibling);
|
||||
}
|
||||
if (component instanceof ChatMessage) {
|
||||
Arrays.stream(((ChatMessage) component).getArgs())
|
||||
.filter(o -> o instanceof IChatBaseComponent)
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package com.willfp.eco.proxy.v1_16_R2;
|
||||
|
||||
import com.willfp.eco.proxy.proxies.VillagerTradeProxy;
|
||||
import com.willfp.eco.core.display.Display;
|
||||
import org.bukkit.craftbukkit.v1_16_R2.inventory.CraftItemStack;
|
||||
import com.willfp.eco.proxy.proxies.VillagerTradeProxy;
|
||||
import org.bukkit.craftbukkit.v1_16_R2.inventory.CraftMerchantRecipe;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.MerchantRecipe;
|
||||
@@ -11,30 +10,56 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public final class VillagerTrade implements VillagerTradeProxy {
|
||||
@Override
|
||||
public void displayTrade(@NotNull final MerchantRecipe merchantRecipe) {
|
||||
/**
|
||||
* Handle.
|
||||
*/
|
||||
private final Field handle;
|
||||
|
||||
/**
|
||||
* Create new Villager Trade.
|
||||
*/
|
||||
public VillagerTrade() {
|
||||
try {
|
||||
// Bukkit MerchantRecipe result
|
||||
Field fResult = MerchantRecipe.class.getDeclaredField("result");
|
||||
fResult.setAccessible(true);
|
||||
ItemStack result = merchantRecipe.getResult();
|
||||
Display.displayAndFinalize(result);
|
||||
fResult.set(merchantRecipe, result);
|
||||
|
||||
// Get NMS MerchantRecipe from CraftMerchantRecipe
|
||||
Field fHandle = CraftMerchantRecipe.class.getDeclaredField("handle");
|
||||
fHandle.setAccessible(true);
|
||||
net.minecraft.server.v1_16_R2.MerchantRecipe handle = (net.minecraft.server.v1_16_R2.MerchantRecipe) fHandle.get(merchantRecipe); // NMS Recipe
|
||||
|
||||
Field fSelling = net.minecraft.server.v1_16_R2.MerchantRecipe.class.getDeclaredField("sellingItem");
|
||||
fSelling.setAccessible(true);
|
||||
|
||||
ItemStack selling = CraftItemStack.asBukkitCopy(handle.sellingItem);
|
||||
Display.displayAndFinalize(selling);
|
||||
|
||||
fSelling.set(handle, CraftItemStack.asNMSCopy(selling));
|
||||
} catch (IllegalAccessException | NoSuchFieldException e) {
|
||||
handle = CraftMerchantRecipe.class.getDeclaredField("handle");
|
||||
handle.setAccessible(true);
|
||||
return;
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
throw new RuntimeException("Error!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public MerchantRecipe displayTrade(@NotNull final MerchantRecipe recipe) {
|
||||
CraftMerchantRecipe oldRecipe = (CraftMerchantRecipe) recipe;
|
||||
|
||||
CraftMerchantRecipe newRecipe = new CraftMerchantRecipe(
|
||||
Display.display(recipe.getResult().clone()),
|
||||
recipe.getUses(),
|
||||
recipe.getMaxUses(),
|
||||
recipe.hasExperienceReward(),
|
||||
recipe.getVillagerExperience(),
|
||||
recipe.getPriceMultiplier()
|
||||
);
|
||||
|
||||
for (ItemStack ingredient : recipe.getIngredients()) {
|
||||
newRecipe.addIngredient(Display.display(ingredient.clone()));
|
||||
}
|
||||
|
||||
getHandle(newRecipe).setSpecialPrice(getHandle(oldRecipe).getSpecialPrice());
|
||||
|
||||
return newRecipe;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private net.minecraft.server.v1_16_R2.MerchantRecipe getHandle(@NotNull final CraftMerchantRecipe recipe) {
|
||||
try {
|
||||
return (net.minecraft.server.v1_16_R2.MerchantRecipe) handle.get(recipe);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Not CMR");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,13 +27,25 @@ public final class ChatComponent implements ChatComponentProxy {
|
||||
}
|
||||
|
||||
IChatBaseComponent chatComponent = (IChatBaseComponent) object;
|
||||
chatComponent.stream().forEach(this::modifyBaseComponent);
|
||||
for (IChatBaseComponent iChatBaseComponent : chatComponent) {
|
||||
if (iChatBaseComponent == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
modifyBaseComponent(iChatBaseComponent);
|
||||
}
|
||||
|
||||
return chatComponent;
|
||||
}
|
||||
|
||||
private void modifyBaseComponent(@NotNull final IChatBaseComponent component) {
|
||||
component.getSiblings().forEach(this::modifyBaseComponent);
|
||||
for (IChatBaseComponent sibling : component.getSiblings()) {
|
||||
if (sibling == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
modifyBaseComponent(sibling);
|
||||
}
|
||||
if (component instanceof ChatMessage) {
|
||||
Arrays.stream(((ChatMessage) component).getArgs())
|
||||
.filter(o -> o instanceof IChatBaseComponent)
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package com.willfp.eco.proxy.v1_16_R3;
|
||||
|
||||
import com.willfp.eco.proxy.proxies.VillagerTradeProxy;
|
||||
import com.willfp.eco.core.display.Display;
|
||||
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack;
|
||||
import com.willfp.eco.proxy.proxies.VillagerTradeProxy;
|
||||
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftMerchantRecipe;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.MerchantRecipe;
|
||||
@@ -11,30 +10,56 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public final class VillagerTrade implements VillagerTradeProxy {
|
||||
@Override
|
||||
public void displayTrade(@NotNull final MerchantRecipe merchantRecipe) {
|
||||
/**
|
||||
* Handle.
|
||||
*/
|
||||
private final Field handle;
|
||||
|
||||
/**
|
||||
* Create new Villager Trade.
|
||||
*/
|
||||
public VillagerTrade() {
|
||||
try {
|
||||
// Bukkit MerchantRecipe result
|
||||
Field fResult = MerchantRecipe.class.getDeclaredField("result");
|
||||
fResult.setAccessible(true);
|
||||
ItemStack result = merchantRecipe.getResult();
|
||||
Display.displayAndFinalize(result);
|
||||
fResult.set(merchantRecipe, result);
|
||||
|
||||
// Get NMS MerchantRecipe from CraftMerchantRecipe
|
||||
Field fHandle = CraftMerchantRecipe.class.getDeclaredField("handle");
|
||||
fHandle.setAccessible(true);
|
||||
net.minecraft.server.v1_16_R3.MerchantRecipe handle = (net.minecraft.server.v1_16_R3.MerchantRecipe) fHandle.get(merchantRecipe); // NMS RecipeR
|
||||
|
||||
Field fSelling = net.minecraft.server.v1_16_R3.MerchantRecipe.class.getDeclaredField("sellingItem");
|
||||
fSelling.setAccessible(true);
|
||||
|
||||
ItemStack selling = CraftItemStack.asBukkitCopy(handle.sellingItem);
|
||||
Display.displayAndFinalize(selling);
|
||||
|
||||
fSelling.set(handle, CraftItemStack.asNMSCopy(selling));
|
||||
} catch (IllegalAccessException | NoSuchFieldException e) {
|
||||
handle = CraftMerchantRecipe.class.getDeclaredField("handle");
|
||||
handle.setAccessible(true);
|
||||
return;
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
throw new RuntimeException("Error!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public MerchantRecipe displayTrade(@NotNull final MerchantRecipe recipe) {
|
||||
CraftMerchantRecipe oldRecipe = (CraftMerchantRecipe) recipe;
|
||||
|
||||
CraftMerchantRecipe newRecipe = new CraftMerchantRecipe(
|
||||
Display.display(recipe.getResult().clone()),
|
||||
recipe.getUses(),
|
||||
recipe.getMaxUses(),
|
||||
recipe.hasExperienceReward(),
|
||||
recipe.getVillagerExperience(),
|
||||
recipe.getPriceMultiplier()
|
||||
);
|
||||
|
||||
for (ItemStack ingredient : recipe.getIngredients()) {
|
||||
newRecipe.addIngredient(Display.display(ingredient.clone()));
|
||||
}
|
||||
|
||||
getHandle(newRecipe).setSpecialPrice(getHandle(oldRecipe).getSpecialPrice());
|
||||
|
||||
return newRecipe;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private net.minecraft.server.v1_16_R3.MerchantRecipe getHandle(@NotNull final CraftMerchantRecipe recipe) {
|
||||
try {
|
||||
return (net.minecraft.server.v1_16_R3.MerchantRecipe) handle.get(recipe);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Not CMR");
|
||||
}
|
||||
}
|
||||
|
||||
6
eco-core/core-nms/v1_17_R1/build.gradle
Normal file
6
eco-core/core-nms/v1_17_R1/build.gradle
Normal file
@@ -0,0 +1,6 @@
|
||||
group 'com.willfp'
|
||||
version rootProject.version
|
||||
|
||||
dependencies {
|
||||
compileOnly 'org.spigotmc:spigot:1.17-R0.1-SNAPSHOT'
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.willfp.eco.proxy.v1_17_R1;
|
||||
|
||||
import com.willfp.eco.proxy.proxies.AutoCraftProxy;
|
||||
import net.minecraft.network.protocol.game.PacketPlayOutAutoRecipe;
|
||||
import net.minecraft.resources.MinecraftKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public final class AutoCraft implements AutoCraftProxy {
|
||||
@Override
|
||||
public void modifyPacket(@NotNull final Object packet) throws NoSuchFieldException, IllegalAccessException {
|
||||
PacketPlayOutAutoRecipe recipePacket = (PacketPlayOutAutoRecipe) packet;
|
||||
Field fKey = recipePacket.getClass().getDeclaredField("b");
|
||||
fKey.setAccessible(true);
|
||||
MinecraftKey key = (MinecraftKey) fKey.get(recipePacket);
|
||||
fKey.set(recipePacket, new MinecraftKey(key.getNamespace(), key.getKey() + "_displayed"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.willfp.eco.proxy.v1_17_R1;
|
||||
|
||||
import com.willfp.eco.proxy.proxies.BlockBreakProxy;
|
||||
import net.minecraft.core.BlockPosition;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public final class BlockBreak implements BlockBreakProxy {
|
||||
@Override
|
||||
public void breakBlock(@NotNull final Player player,
|
||||
@NotNull final Block block) {
|
||||
((CraftPlayer) player).getHandle().d.breakBlock(new BlockPosition(block.getX(), block.getY(), block.getZ()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package com.willfp.eco.proxy.v1_17_R1;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.willfp.eco.proxy.proxies.ChatComponentProxy;
|
||||
import com.willfp.eco.core.display.Display;
|
||||
import net.minecraft.nbt.MojangsonParser;
|
||||
import net.minecraft.network.chat.ChatBaseComponent;
|
||||
import net.minecraft.network.chat.ChatHoverable;
|
||||
import net.minecraft.network.chat.ChatMessage;
|
||||
import net.minecraft.network.chat.ChatModifier;
|
||||
import net.minecraft.network.chat.IChatBaseComponent;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public final class ChatComponent implements ChatComponentProxy {
|
||||
@Override
|
||||
public Object modifyComponent(@NotNull final Object object) {
|
||||
if (!(object instanceof IChatBaseComponent)) {
|
||||
return object;
|
||||
}
|
||||
|
||||
IChatBaseComponent chatComponent = (IChatBaseComponent) object;
|
||||
for (IChatBaseComponent iChatBaseComponent : chatComponent) {
|
||||
if (iChatBaseComponent == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
modifyBaseComponent(iChatBaseComponent);
|
||||
}
|
||||
|
||||
return chatComponent;
|
||||
}
|
||||
|
||||
private void modifyBaseComponent(@NotNull final IChatBaseComponent component) {
|
||||
for (IChatBaseComponent sibling : component.getSiblings()) {
|
||||
if (sibling == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
modifyBaseComponent(sibling);
|
||||
}
|
||||
if (component instanceof ChatMessage) {
|
||||
Arrays.stream(((ChatMessage) component).getArgs())
|
||||
.filter(o -> o instanceof IChatBaseComponent)
|
||||
.map(o -> (IChatBaseComponent) o)
|
||||
.forEach(this::modifyBaseComponent);
|
||||
}
|
||||
|
||||
ChatHoverable hoverable = component.getChatModifier().getHoverEvent();
|
||||
|
||||
if (hoverable == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
JsonObject jsonObject = hoverable.b();
|
||||
JsonElement json = hoverable.b().get("contents");
|
||||
if (json.getAsJsonObject().get("id") == null) {
|
||||
return;
|
||||
}
|
||||
if (json.getAsJsonObject().get("tag") == null) {
|
||||
return;
|
||||
}
|
||||
String id = json.getAsJsonObject().get("id").toString();
|
||||
String tag = json.getAsJsonObject().get("tag").toString();
|
||||
ItemStack itemStack = getFromTag(tag, id);
|
||||
|
||||
Display.displayAndFinalize(itemStack);
|
||||
|
||||
json.getAsJsonObject().remove("tag");
|
||||
String newTag = toJson(itemStack);
|
||||
json.getAsJsonObject().add("tag", new JsonPrimitive(newTag));
|
||||
|
||||
jsonObject.remove("contents");
|
||||
jsonObject.add("contents", json);
|
||||
ChatHoverable newHoverable = ChatHoverable.a(jsonObject);
|
||||
ChatModifier modifier = component.getChatModifier();
|
||||
modifier = modifier.setChatHoverable(newHoverable);
|
||||
|
||||
((ChatBaseComponent) component).setChatModifier(modifier);
|
||||
}
|
||||
|
||||
private static ItemStack getFromTag(@NotNull final String jsonTag,
|
||||
@NotNull final String id) {
|
||||
String processedId = id;
|
||||
String processedJsonTag = jsonTag;
|
||||
processedId = processedId.replace("minecraft:", "");
|
||||
processedId = processedId.toUpperCase();
|
||||
processedId = processedId.replace("\"", "");
|
||||
processedJsonTag = processedJsonTag.substring(1, processedJsonTag.length() - 1);
|
||||
processedJsonTag = processedJsonTag.replace("id:", "\"id\":");
|
||||
processedJsonTag = processedJsonTag.replace("\\", "");
|
||||
Material material = Material.getMaterial(processedId);
|
||||
|
||||
assert material != null;
|
||||
ItemStack itemStack = new ItemStack(material);
|
||||
net.minecraft.world.item.ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack);
|
||||
|
||||
try {
|
||||
nmsStack.setTag(MojangsonParser.parse(processedJsonTag));
|
||||
} catch (CommandSyntaxException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return CraftItemStack.asBukkitCopy(nmsStack);
|
||||
}
|
||||
|
||||
private static String toJson(@NotNull final ItemStack itemStack) {
|
||||
return CraftItemStack.asNMSCopy(itemStack).getOrCreateTag().toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.willfp.eco.proxy.v1_17_R1;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.properties.Property;
|
||||
import com.willfp.eco.proxy.proxies.SkullProxy;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.UUID;
|
||||
|
||||
public final class Skull implements SkullProxy {
|
||||
/**
|
||||
* Cached method to set the gameProfile.
|
||||
*/
|
||||
private Method setProfile = null;
|
||||
|
||||
@Override
|
||||
public void setSkullTexture(@NotNull final SkullMeta meta,
|
||||
@NotNull final String base64) {
|
||||
try {
|
||||
if (setProfile == null) {
|
||||
setProfile = meta.getClass().getDeclaredMethod("setProfile", GameProfile.class);
|
||||
setProfile.setAccessible(true);
|
||||
}
|
||||
|
||||
UUID uuid = new UUID(
|
||||
base64.substring(base64.length() - 20).hashCode(),
|
||||
base64.substring(base64.length() - 10).hashCode()
|
||||
);
|
||||
|
||||
GameProfile profile = new GameProfile(uuid, "talismans");
|
||||
profile.getProperties().put("textures", new Property("textures", base64));
|
||||
|
||||
setProfile.invoke(meta, profile);
|
||||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.willfp.eco.proxy.v1_17_R1;
|
||||
|
||||
import com.willfp.eco.proxy.proxies.TridentStackProxy;
|
||||
import org.bukkit.entity.Trident;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public final class TridentStack implements TridentStackProxy {
|
||||
@Override
|
||||
public ItemStack getTridentStack(@NotNull final Trident trident) {
|
||||
return trident.getItem();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.willfp.eco.proxy.v1_17_R1;
|
||||
|
||||
import com.willfp.eco.core.display.Display;
|
||||
import com.willfp.eco.proxy.proxies.VillagerTradeProxy;
|
||||
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftMerchantRecipe;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.MerchantRecipe;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public final class VillagerTrade implements VillagerTradeProxy {
|
||||
/**
|
||||
* Handle.
|
||||
*/
|
||||
private final Field handle;
|
||||
|
||||
/**
|
||||
* Create new Villager Trade.
|
||||
*/
|
||||
public VillagerTrade() {
|
||||
try {
|
||||
handle = CraftMerchantRecipe.class.getDeclaredField("handle");
|
||||
handle.setAccessible(true);
|
||||
return;
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
throw new RuntimeException("Error!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public MerchantRecipe displayTrade(@NotNull final MerchantRecipe recipe) {
|
||||
CraftMerchantRecipe oldRecipe = (CraftMerchantRecipe) recipe;
|
||||
|
||||
CraftMerchantRecipe newRecipe = new CraftMerchantRecipe(
|
||||
Display.display(recipe.getResult().clone()),
|
||||
recipe.getUses(),
|
||||
recipe.getMaxUses(),
|
||||
recipe.hasExperienceReward(),
|
||||
recipe.getVillagerExperience(),
|
||||
recipe.getPriceMultiplier()
|
||||
);
|
||||
|
||||
for (ItemStack ingredient : recipe.getIngredients()) {
|
||||
newRecipe.addIngredient(Display.display(ingredient.clone()));
|
||||
}
|
||||
|
||||
getHandle(newRecipe).setSpecialPrice(getHandle(oldRecipe).getSpecialPrice());
|
||||
|
||||
return newRecipe;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private net.minecraft.world.item.trading.MerchantRecipe getHandle(@NotNull final CraftMerchantRecipe recipe) {
|
||||
try {
|
||||
return (net.minecraft.world.item.trading.MerchantRecipe) handle.get(recipe);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Not CMR");
|
||||
}
|
||||
}
|
||||
@@ -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.data.Data;
|
||||
import com.willfp.eco.core.display.Display;
|
||||
import com.willfp.eco.core.display.DisplayModule;
|
||||
import com.willfp.eco.core.integrations.IntegrationLoader;
|
||||
@@ -12,6 +13,7 @@ import com.willfp.eco.core.integrations.mcmmo.McmmoManager;
|
||||
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.display.PacketAutoRecipe;
|
||||
import com.willfp.eco.spigot.display.PacketChat;
|
||||
import com.willfp.eco.spigot.display.PacketOpenWindowMerchant;
|
||||
@@ -23,9 +25,8 @@ 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.integrations.anticheat.AnticheatAAC;
|
||||
import com.willfp.eco.spigot.integrations.anticheat.AnticheatMatrix;
|
||||
import com.willfp.eco.spigot.integrations.anticheat.AnticheatNCP;
|
||||
import com.willfp.eco.spigot.gui.GUIListener;
|
||||
import com.willfp.eco.spigot.integrations.anticheat.*;
|
||||
import com.willfp.eco.spigot.integrations.antigrief.AntigriefCombatLogX;
|
||||
import com.willfp.eco.spigot.integrations.antigrief.AntigriefFactionsUUID;
|
||||
import com.willfp.eco.spigot.integrations.antigrief.AntigriefGriefPrevention;
|
||||
@@ -42,6 +43,7 @@ import lombok.Getter;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -53,6 +55,11 @@ public class EcoSpigotPlugin extends EcoPlugin {
|
||||
@Getter
|
||||
private static EcoSpigotPlugin instance;
|
||||
|
||||
/**
|
||||
* data.yml.
|
||||
*/
|
||||
private final DataYml dataYml;
|
||||
|
||||
/**
|
||||
* Create a new instance of eco.
|
||||
*/
|
||||
@@ -69,21 +76,23 @@ public class EcoSpigotPlugin extends EcoPlugin {
|
||||
|
||||
TridentStackProxy tridentStackProxy = InternalProxyUtils.getProxy(TridentStackProxy.class);
|
||||
TridentUtils.initialize(tridentStackProxy::getTridentStack);
|
||||
|
||||
this.dataYml = new DataYml(this);
|
||||
Data.init(this.dataYml);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enable() {
|
||||
new CollatedRunnable(this);
|
||||
this.getEventManager().registerListener(new NaturalExpGainListeners());
|
||||
this.getEventManager().registerListener(new ArmorListener());
|
||||
this.getEventManager().registerListener(new DispenserArmorListener());
|
||||
this.getEventManager().registerListener(new EntityDeathByEntityListeners(this));
|
||||
this.getEventManager().registerListener(new ShapedRecipeListener());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable() {
|
||||
|
||||
try {
|
||||
Data.save(this.dataYml);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -117,6 +126,8 @@ public class EcoSpigotPlugin extends EcoPlugin {
|
||||
new IntegrationLoader("AAC5", () -> AnticheatManager.register(this, new AnticheatAAC())),
|
||||
new IntegrationLoader("Matrix", () -> AnticheatManager.register(this, new AnticheatMatrix())),
|
||||
new IntegrationLoader("NoCheatPlus", () -> AnticheatManager.register(this, new AnticheatNCP())),
|
||||
new IntegrationLoader("Spartan", () -> AnticheatManager.register(this, new AnticheatSpartan())),
|
||||
new IntegrationLoader("Vulcan", () -> AnticheatManager.register(this, new AnticheatVulcan())),
|
||||
|
||||
// Misc
|
||||
new IntegrationLoader("mcMMO", () -> McmmoManager.register(new McmmoIntegrationImpl()))
|
||||
@@ -130,19 +141,31 @@ public class EcoSpigotPlugin extends EcoPlugin {
|
||||
|
||||
@Override
|
||||
public List<AbstractPacketAdapter> getPacketAdapters() {
|
||||
return Arrays.asList(
|
||||
List<AbstractPacketAdapter> adapters = new ArrayList<>(Arrays.asList(
|
||||
new PacketAutoRecipe(this),
|
||||
new PacketChat(this),
|
||||
new PacketOpenWindowMerchant(this),
|
||||
new PacketSetCreativeSlot(this),
|
||||
new PacketSetSlot(this),
|
||||
new PacketWindowItems(this)
|
||||
);
|
||||
));
|
||||
|
||||
if (!this.getConfigYml().getBool("disable-display-on-villagers")) {
|
||||
adapters.add(new PacketOpenWindowMerchant(this));
|
||||
}
|
||||
|
||||
return adapters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Listener> getListeners() {
|
||||
return new ArrayList<>();
|
||||
return Arrays.asList(
|
||||
new NaturalExpGainListeners(),
|
||||
new ArmorListener(),
|
||||
new DispenserArmorListener(),
|
||||
new EntityDeathByEntityListeners(this),
|
||||
new ShapedRecipeListener(),
|
||||
new GUIListener(this)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,23 @@
|
||||
package com.willfp.eco.spigot.display;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.events.ListenerPriority;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.willfp.eco.core.AbstractPacketAdapter;
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.proxy.proxies.VillagerTradeProxy;
|
||||
import com.willfp.eco.spigot.InternalProxyUtils;
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.AbstractPacketAdapter;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.MerchantRecipe;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class PacketOpenWindowMerchant extends AbstractPacketAdapter {
|
||||
/**
|
||||
@@ -20,16 +26,32 @@ public class PacketOpenWindowMerchant extends AbstractPacketAdapter {
|
||||
* @param plugin The plugin to listen through.
|
||||
*/
|
||||
public PacketOpenWindowMerchant(@NotNull final EcoPlugin plugin) {
|
||||
super(plugin, PacketType.Play.Server.OPEN_WINDOW_MERCHANT, false);
|
||||
super(plugin, PacketType.Play.Server.OPEN_WINDOW_MERCHANT, ListenerPriority.MONITOR, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSend(@NotNull final PacketContainer packet,
|
||||
@NotNull final Player player) {
|
||||
List<MerchantRecipe> recipes = packet.getMerchantRecipeLists().readSafely(0);
|
||||
@NotNull final Player player,
|
||||
@NotNull final PacketEvent event) {
|
||||
List<MerchantRecipe> recipes = new ArrayList<>();
|
||||
|
||||
recipes = recipes.stream().peek(merchantRecipe -> InternalProxyUtils.getProxy(VillagerTradeProxy.class).displayTrade(merchantRecipe)).collect(Collectors.toList());
|
||||
if (((EcoPlugin) this.getPlugin()).getConfigYml().getBool("villager-display-fix")) {
|
||||
for (MerchantRecipe recipe : packet.getMerchantRecipeLists().read(0)) {
|
||||
ItemStack result = recipe.getResult();
|
||||
ItemMeta meta = result.getItemMeta();
|
||||
if (meta != null) {
|
||||
meta.removeItemFlags(ItemFlag.HIDE_ENCHANTS, ItemFlag.HIDE_POTION_EFFECTS);
|
||||
meta.getPersistentDataContainer().remove(NamespacedKey.fromString("ecoenchants:ecoenchantlore-skip"));
|
||||
result.setItemMeta(meta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
packet.getMerchantRecipeLists().writeSafely(0, recipes);
|
||||
for (MerchantRecipe recipe : packet.getMerchantRecipeLists().read(0)) {
|
||||
MerchantRecipe newRecipe = InternalProxyUtils.getProxy(VillagerTradeProxy.class).displayTrade(recipe);
|
||||
recipes.add(newRecipe);
|
||||
}
|
||||
|
||||
packet.getMerchantRecipeLists().write(0, recipes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
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 {
|
||||
/**
|
||||
* Pass an {@link EcoPlugin} in order to interface with it.
|
||||
*
|
||||
* @param plugin The plugin to manage.
|
||||
*/
|
||||
public GUIListener(@NotNull final EcoPlugin plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void handleSlotClick(@NotNull final InventoryClickEvent event) {
|
||||
if (!(event.getWhoClicked() instanceof Player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.getClickedInventory() == null) {
|
||||
return;
|
||||
}
|
||||
Menu menu = MenuHandler.getMenu(event.getClickedInventory());
|
||||
if (menu == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int row = Math.floorDiv(event.getSlot(), 9);
|
||||
int column = event.getSlot() - (row * 9);
|
||||
|
||||
EcoSlot slot = (EcoSlot) menu.getSlot(row, column);
|
||||
event.setCancelled(true);
|
||||
slot.handleInventoryClick(event);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void handleClose(@NotNull final InventoryCloseEvent event) {
|
||||
if (!(event.getPlayer() instanceof Player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
EcoMenu menu = (EcoMenu) MenuHandler.getMenu(event.getInventory());
|
||||
if (menu == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
menu.handleClose(event);
|
||||
|
||||
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());
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.willfp.eco.spigot.integrations.anticheat;
|
||||
|
||||
import com.willfp.eco.core.integrations.anticheat.AnticheatWrapper;
|
||||
import me.frep.vulcan.api.event.VulcanFlagEvent;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class AnticheatVulcan implements AnticheatWrapper, Listener {
|
||||
/**
|
||||
* Currently exempt players.
|
||||
*/
|
||||
private final Set<UUID> exempt = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public String getPluginName() {
|
||||
return "Vulcan";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exempt(@NotNull final Player player) {
|
||||
this.exempt.add(player.getUniqueId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unexempt(@NotNull final Player player) {
|
||||
this.exempt.remove(player.getUniqueId());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
private void onViolate(@NotNull final VulcanFlagEvent event) {
|
||||
if (!exempt.contains(event.getPlayer().getUniqueId())) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
disable-display-on-villagers: false
|
||||
villager-display-fix: false
|
||||
0
eco-core/core-plugin/src/main/resources/data.yml
Normal file
0
eco-core/core-plugin/src/main/resources/data.yml
Normal file
@@ -10,6 +10,7 @@ loadbefore:
|
||||
- StatTrackers
|
||||
- EcoArmor
|
||||
- EcoBosses
|
||||
- EcoSkills
|
||||
depend:
|
||||
- ProtocolLib
|
||||
softdepend:
|
||||
|
||||
@@ -2,12 +2,14 @@ package com.willfp.eco.proxy.proxies;
|
||||
|
||||
import com.willfp.eco.core.proxy.AbstractProxy;
|
||||
import org.bukkit.inventory.MerchantRecipe;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface VillagerTradeProxy extends AbstractProxy {
|
||||
/**
|
||||
* Apply enchant display to the result of trades.
|
||||
* Display a MerchantRecipe.
|
||||
*
|
||||
* @param merchantRecipe The recipe to modify.
|
||||
* @param recipe The recipe.
|
||||
* @return The new recipe.
|
||||
*/
|
||||
void displayTrade(MerchantRecipe merchantRecipe);
|
||||
MerchantRecipe displayTrade(@NotNull MerchantRecipe recipe);
|
||||
}
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
version = 5.0.0
|
||||
version = 5.4.0
|
||||
plugin-name = eco
|
||||
BIN
lib/VulcanAPI.jar
Normal file
BIN
lib/VulcanAPI.jar
Normal file
Binary file not shown.
@@ -7,5 +7,6 @@ include ':eco-core:core-nms'
|
||||
include ':eco-core:core-nms:v1_16_R1'
|
||||
include ':eco-core:core-nms:v1_16_R2'
|
||||
include ':eco-core:core-nms:v1_16_R3'
|
||||
include ':eco-core:core-nms:v1_17_R1'
|
||||
include ':eco-core:core-proxy'
|
||||
include ':eco-core:core-plugin'
|
||||
Reference in New Issue
Block a user