Compare commits
76 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
00ea3506ca | ||
|
|
521659cfec | ||
|
|
bbe5f1eba4 | ||
|
|
eae5d29f8d | ||
|
|
c878d6fd12 | ||
|
|
2b97c0072f | ||
|
|
63079df745 | ||
|
|
079b41e877 | ||
|
|
1aaab459d8 | ||
|
|
db78c2eb4c | ||
|
|
02fd07b3c8 | ||
|
|
3de2e53031 | ||
|
|
cb088bb70b | ||
|
|
36fca7016f | ||
|
|
7e1137da06 | ||
|
|
0da104d614 | ||
|
|
9095de7d19 | ||
|
|
7a8abac1a2 | ||
|
|
1ddcb6e964 | ||
|
|
4d0858ad84 | ||
|
|
3d05695a36 | ||
|
|
d676be15ce | ||
|
|
16848caec1 | ||
|
|
ef26fe4629 | ||
|
|
29fbd785d7 | ||
|
|
8c73676ee0 | ||
|
|
ebf27d28d9 | ||
|
|
317bc13f65 | ||
|
|
b8ec0ee6fc | ||
|
|
307e57c902 | ||
|
|
db0d55659f | ||
|
|
548529feb3 | ||
|
|
fb56baf452 | ||
|
|
5d18b424d7 | ||
|
|
7be9a1bd10 | ||
|
|
97c39b56dd | ||
|
|
3a9f5bc139 | ||
|
|
1e5955f249 | ||
|
|
bad076bbe9 | ||
|
|
e219b2f33c | ||
|
|
2f7603409e | ||
|
|
28cdb65176 | ||
|
|
03ae9e89b3 | ||
|
|
2d074bc186 | ||
|
|
7e4422f6e2 | ||
|
|
5b29c90457 | ||
|
|
4ebc1a18a1 | ||
|
|
db20bed6e0 | ||
|
|
0826da6cfc | ||
|
|
6d8fce3462 | ||
|
|
eedb1404b6 | ||
|
|
299abe4568 | ||
|
|
98e1f19145 | ||
|
|
424e2ff43d | ||
|
|
3a899226a3 | ||
|
|
8336eee892 | ||
|
|
a48f756582 | ||
|
|
2aa463d083 | ||
|
|
ea833de9f7 | ||
|
|
3c0822310d | ||
|
|
d5cbc1d497 | ||
|
|
c912ad1c9c | ||
|
|
752f38ef25 | ||
|
|
a5525ab332 | ||
|
|
1b442f400d | ||
|
|
3c9c0bcef4 | ||
|
|
3a7a938e7f | ||
|
|
32c17aa3ae | ||
|
|
e451732876 | ||
|
|
53f81c0a03 | ||
|
|
f60d91c5f3 | ||
|
|
a9bdca56a5 | ||
|
|
3516d5881e | ||
|
|
95cecc2b2a | ||
|
|
f276026972 | ||
|
|
d2c6cc0d2e |
8
.github/workflows/java-ci.yml
vendored
8
.github/workflows/java-ci.yml
vendored
@@ -14,11 +14,11 @@ jobs:
|
||||
id: vars
|
||||
run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
|
||||
|
||||
- name: Set up JDK 16
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: 16
|
||||
distribution: 'temurin'
|
||||
java-version: 17
|
||||
|
||||
- name: Setup build cache
|
||||
uses: actions/cache@v2.1.6
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
|
||||
- run: ./gradlew build
|
||||
- run: ./gradlew build --full-stacktrace
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
|
||||
6
.github/workflows/publish-release.yml
vendored
6
.github/workflows/publish-release.yml
vendored
@@ -12,11 +12,11 @@ jobs:
|
||||
- name: Checkout latest code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set up JDK 16
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: 16
|
||||
distribution: 'temurin'
|
||||
java-version: 17
|
||||
|
||||
- name: Setup build cache
|
||||
uses: actions/cache@v2.1.6
|
||||
|
||||
@@ -21,4 +21,4 @@
|
||||
|
||||
## Other
|
||||
- All drops **must** be sent through a DropQueue - calls to World#dropItem will get your PR rejected.
|
||||
- eco is built with java 16.
|
||||
- eco is built with java 17.
|
||||
@@ -12,6 +12,7 @@ dependencies {
|
||||
implementation(project(":eco-core:core-backend"))
|
||||
implementation(project(":eco-core:core-nms:v1_16_R3"))
|
||||
implementation(project(path = ":eco-core:core-nms:v1_17_R1", configuration = "reobf"))
|
||||
implementation(project(":eco-core:core-nms:v1_18_R1"))
|
||||
}
|
||||
|
||||
allprojects {
|
||||
@@ -25,13 +26,16 @@ allprojects {
|
||||
mavenLocal()
|
||||
maven("https://jitpack.io")
|
||||
|
||||
// CustomCrafting
|
||||
maven("https://maven.wolfyscript.com/repository/public/")
|
||||
|
||||
// SuperiorSkyblock2
|
||||
maven("https://repo.bg-software.com/repository/api/")
|
||||
|
||||
// NMS (for jitpack compilation)
|
||||
maven("https://repo.codemc.org/repository/nms/")
|
||||
|
||||
// bStats, mcMMO, BentoBox
|
||||
// mcMMO, BentoBox
|
||||
maven("https://repo.codemc.org/repository/maven-public/")
|
||||
|
||||
// Spigot API, Bungee API
|
||||
@@ -65,6 +69,11 @@ allprojects {
|
||||
// Test
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.1")
|
||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1")
|
||||
|
||||
// Adventure
|
||||
compileOnly("net.kyori:adventure-api:4.9.3")
|
||||
compileOnly("net.kyori:adventure-text-serializer-gson:4.9.3")
|
||||
compileOnly("net.kyori:adventure-text-serializer-legacy:4.9.3")
|
||||
}
|
||||
|
||||
tasks.withType<JavaCompile> {
|
||||
@@ -93,8 +102,8 @@ allprojects {
|
||||
}
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_16
|
||||
targetCompatibility = JavaVersion.VERSION_16
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
withSourcesJar()
|
||||
}
|
||||
|
||||
|
||||
@@ -9,9 +9,6 @@ dependencies {
|
||||
// Adventure
|
||||
compileOnly 'net.kyori:adventure-platform-bukkit:4.0.0'
|
||||
compileOnly 'net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT'
|
||||
compileOnly 'net.kyori:adventure-api:4.9.2'
|
||||
compileOnly 'net.kyori:adventure-text-serializer-gson:4.9.2'
|
||||
compileOnly 'net.kyori:adventure-text-serializer-legacy:4.9.2'
|
||||
|
||||
// Other
|
||||
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
|
||||
|
||||
@@ -41,11 +41,19 @@ public class Prerequisite {
|
||||
"Requires server to have vault"
|
||||
);
|
||||
|
||||
/**
|
||||
* Requires the server to be running 1.18.
|
||||
*/
|
||||
public static final Prerequisite HAS_1_18 = new Prerequisite(
|
||||
() -> ProxyConstants.NMS_VERSION.contains("18"),
|
||||
"Requires server to be running 1.18+"
|
||||
);
|
||||
|
||||
/**
|
||||
* Requires the server to be running 1.17.
|
||||
*/
|
||||
public static final Prerequisite HAS_1_17 = new Prerequisite(
|
||||
() -> ProxyConstants.NMS_VERSION.contains("17"),
|
||||
() -> ProxyConstants.NMS_VERSION.contains("17") || HAS_1_18.isMet(),
|
||||
"Requires server to be running 1.17+"
|
||||
);
|
||||
|
||||
|
||||
@@ -16,4 +16,40 @@ public class ConfigYml extends YamlBaseConfig {
|
||||
public ConfigYml(@NotNull final EcoPlugin plugin) {
|
||||
super("config", true, plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Config.yml.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
* @param removeUnused Remove unused.
|
||||
*/
|
||||
public ConfigYml(@NotNull final EcoPlugin plugin,
|
||||
final boolean removeUnused) {
|
||||
super("config", removeUnused, plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Config.yml.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
* @param name The config name.
|
||||
*/
|
||||
public ConfigYml(@NotNull final EcoPlugin plugin,
|
||||
@NotNull final String name) {
|
||||
super(name, true, plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Config.yml.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
* @param name The config name.
|
||||
* @param removeUnused Remove unused.
|
||||
*/
|
||||
public ConfigYml(@NotNull final EcoPlugin plugin,
|
||||
@NotNull final String name,
|
||||
final boolean removeUnused) {
|
||||
super(name, removeUnused, plugin);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -524,6 +524,25 @@ public interface Config extends Cloneable {
|
||||
@Nullable
|
||||
List<Double> getDoublesOrNull(@NotNull String path);
|
||||
|
||||
/**
|
||||
* 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<? extends Config> 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<? extends Config> getSubsectionsOrNull(@NotNull String path);
|
||||
|
||||
|
||||
/**
|
||||
* Clone the config.
|
||||
*
|
||||
|
||||
@@ -173,6 +173,16 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
|
||||
return handle.getDoublesOrNull(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<? extends Config> getSubsections(@NotNull final String path) {
|
||||
return handle.getSubsections(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable List<? extends Config> getSubsectionsOrNull(@NotNull final String path) {
|
||||
return handle.getSubsectionsOrNull(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Config clone() {
|
||||
return handle.clone();
|
||||
|
||||
@@ -14,16 +14,23 @@ import java.io.StringReader;
|
||||
*/
|
||||
public class YamlTransientConfig extends YamlConfigWrapper {
|
||||
/**
|
||||
* @param config The YamlConfiguration handle.
|
||||
* @param config The YamlConfiguration handle.
|
||||
*/
|
||||
public YamlTransientConfig(@NotNull final YamlConfiguration config) {
|
||||
super(Eco.getHandler().getConfigFactory().createYamlConfig(config));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param contents The contents of the config.
|
||||
* @param contents The contents of the config.
|
||||
*/
|
||||
public YamlTransientConfig(@NotNull final String contents) {
|
||||
super(Eco.getHandler().getConfigFactory().createYamlConfig(YamlConfiguration.loadConfiguration(new StringReader(contents))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new empty transient config.
|
||||
*/
|
||||
public YamlTransientConfig() {
|
||||
super(Eco.getHandler().getConfigFactory().createYamlConfig(YamlConfiguration.loadConfiguration(new StringReader(""))));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
package com.willfp.eco.core.events;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.player.PlayerEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Called on DropQueue push.
|
||||
*/
|
||||
public class DropQueuePushEvent extends PlayerEvent implements Cancellable {
|
||||
/**
|
||||
* Cancel state.
|
||||
*/
|
||||
private boolean cancelled;
|
||||
|
||||
/**
|
||||
* If telekinetic.
|
||||
*/
|
||||
private final boolean isTelekinetic;
|
||||
|
||||
/**
|
||||
* The items.
|
||||
*/
|
||||
private final Collection<? extends ItemStack> items;
|
||||
|
||||
/**
|
||||
* The xp.
|
||||
*/
|
||||
private final int xp;
|
||||
|
||||
/**
|
||||
* The location.
|
||||
*/
|
||||
private final Location location;
|
||||
|
||||
/**
|
||||
* Bukkit parity.
|
||||
*/
|
||||
private static final HandlerList HANDLERS = new HandlerList();
|
||||
|
||||
/**
|
||||
* Create a new DropQueuePushEvent.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param items The items.
|
||||
* @param location The location.
|
||||
* @param xp The xp.
|
||||
* @param isTelekinetic If the event is telekinetic.
|
||||
*/
|
||||
public DropQueuePushEvent(@NotNull final Player player,
|
||||
@NotNull final Collection<? extends ItemStack> items,
|
||||
@NotNull final Location location,
|
||||
final int xp,
|
||||
final boolean isTelekinetic) {
|
||||
super(player);
|
||||
this.items = items;
|
||||
this.location = location;
|
||||
this.xp = xp;
|
||||
this.isTelekinetic = isTelekinetic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of handlers handling this event.
|
||||
*
|
||||
* @return A list of handlers handling this event.
|
||||
*/
|
||||
@Override
|
||||
@NotNull
|
||||
public HandlerList getHandlers() {
|
||||
return HANDLERS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bukkit parity.
|
||||
*
|
||||
* @return The handler list.
|
||||
*/
|
||||
public static HandlerList getHandlerList() {
|
||||
return HANDLERS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cancel state.
|
||||
*
|
||||
* @return The cancel state.
|
||||
*/
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return this.cancelled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cancel state.
|
||||
*
|
||||
* @param cancelled If cancelled.
|
||||
*/
|
||||
@Override
|
||||
public void setCancelled(final boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the items to be dropped.
|
||||
*
|
||||
* @return The items.
|
||||
*/
|
||||
public Collection<? extends ItemStack> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the xp to be dropped.
|
||||
*
|
||||
* @return The xp.
|
||||
*/
|
||||
public int getXp() {
|
||||
return xp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the location.
|
||||
*
|
||||
* @return The location.
|
||||
*/
|
||||
public Location getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get force telekinesis state.
|
||||
*
|
||||
* @return The force telekinesis state.
|
||||
*/
|
||||
public boolean isTelekinetic() {
|
||||
return this.isTelekinetic;
|
||||
}
|
||||
}
|
||||
@@ -70,14 +70,14 @@ public interface FastItemStack {
|
||||
*
|
||||
* @param hideFlags The flags.
|
||||
*/
|
||||
void addItemFlags(ItemFlag... hideFlags);
|
||||
void addItemFlags(@NotNull ItemFlag... hideFlags);
|
||||
|
||||
/**
|
||||
* Remove ItemFlags.
|
||||
*
|
||||
* @param hideFlags The flags.
|
||||
*/
|
||||
void removeItemFlags(ItemFlag... hideFlags);
|
||||
void removeItemFlags(@NotNull ItemFlag... hideFlags);
|
||||
|
||||
/**
|
||||
* Get the ItemFlags.
|
||||
@@ -92,7 +92,7 @@ public interface FastItemStack {
|
||||
* @param flag The flag.
|
||||
* @return If the flag is present.
|
||||
*/
|
||||
boolean hasItemFlag(ItemFlag flag);
|
||||
boolean hasItemFlag(@NotNull ItemFlag flag);
|
||||
|
||||
/**
|
||||
* Get the Bukkit ItemStack again.
|
||||
|
||||
@@ -37,6 +37,17 @@ public final class AntigriefManager {
|
||||
REGISTERED.remove(antigrief);
|
||||
}
|
||||
|
||||
/**
|
||||
* Can player pickup item.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param location The location.
|
||||
* @return If player can pick up item.
|
||||
*/
|
||||
public static boolean canPickupItem(@NotNull final Player player, @NotNull final Location location) {
|
||||
return REGISTERED.stream().allMatch(antigriefWrapper -> antigriefWrapper.canPickupItem(player, location));
|
||||
}
|
||||
|
||||
/**
|
||||
* Can player break block.
|
||||
*
|
||||
@@ -45,7 +56,7 @@ public final class AntigriefManager {
|
||||
* @return If player can break block.
|
||||
*/
|
||||
public static boolean canBreakBlock(@NotNull final Player player,
|
||||
@NotNull final Block block) {
|
||||
@NotNull final Block block) {
|
||||
return REGISTERED.stream().allMatch(antigriefWrapper -> antigriefWrapper.canBreakBlock(player, block));
|
||||
}
|
||||
|
||||
@@ -57,7 +68,7 @@ public final class AntigriefManager {
|
||||
* @return If player can create explosion.
|
||||
*/
|
||||
public static boolean canCreateExplosion(@NotNull final Player player,
|
||||
@NotNull final Location location) {
|
||||
@NotNull final Location location) {
|
||||
return REGISTERED.stream().allMatch(antigriefWrapper -> antigriefWrapper.canCreateExplosion(player, location));
|
||||
}
|
||||
|
||||
@@ -69,7 +80,7 @@ public final class AntigriefManager {
|
||||
* @return If player can place block.
|
||||
*/
|
||||
public static boolean canPlaceBlock(@NotNull final Player player,
|
||||
@NotNull final Block block) {
|
||||
@NotNull final Block block) {
|
||||
return REGISTERED.stream().allMatch(antigriefWrapper -> antigriefWrapper.canPlaceBlock(player, block));
|
||||
}
|
||||
|
||||
@@ -81,7 +92,7 @@ public final class AntigriefManager {
|
||||
* @return If player can injure.
|
||||
*/
|
||||
public static boolean canInjure(@NotNull final Player player,
|
||||
@NotNull final LivingEntity victim) {
|
||||
@NotNull final LivingEntity victim) {
|
||||
return REGISTERED.stream().allMatch(antigriefWrapper -> antigriefWrapper.canInjure(player, victim));
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Wrapper class for antigrief integrations.
|
||||
@@ -17,7 +18,7 @@ public interface AntigriefWrapper extends Integration {
|
||||
* @param block The block.
|
||||
* @return If player can break block.
|
||||
*/
|
||||
boolean canBreakBlock(Player player, Block block);
|
||||
boolean canBreakBlock(@NotNull Player player, @NotNull Block block);
|
||||
|
||||
/**
|
||||
* Can player create explosion at location.
|
||||
@@ -26,7 +27,7 @@ public interface AntigriefWrapper extends Integration {
|
||||
* @param location The location.
|
||||
* @return If player can create explosion.
|
||||
*/
|
||||
boolean canCreateExplosion(Player player, Location location);
|
||||
boolean canCreateExplosion(@NotNull Player player, @NotNull Location location);
|
||||
|
||||
/**
|
||||
* Can player place block.
|
||||
@@ -35,7 +36,7 @@ public interface AntigriefWrapper extends Integration {
|
||||
* @param block The block.
|
||||
* @return If player can place block.
|
||||
*/
|
||||
boolean canPlaceBlock(Player player, Block block);
|
||||
boolean canPlaceBlock(@NotNull Player player, @NotNull Block block);
|
||||
|
||||
/**
|
||||
* Can player injure living entity.
|
||||
@@ -44,5 +45,15 @@ public interface AntigriefWrapper extends Integration {
|
||||
* @param victim The victim.
|
||||
* @return If player can injure.
|
||||
*/
|
||||
boolean canInjure(Player player, LivingEntity victim);
|
||||
boolean canInjure(@NotNull Player player, @NotNull LivingEntity victim);
|
||||
|
||||
/**
|
||||
* Can player pick up item.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param location The location.
|
||||
* @return If player can pick up item.
|
||||
*/
|
||||
boolean canPickupItem(@NotNull Player player, @NotNull Location location);
|
||||
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ public final class Items {
|
||||
* @param item The item.
|
||||
*/
|
||||
public static void registerCustomItem(@NotNull final NamespacedKey key,
|
||||
@NotNull final TestableItem item) {
|
||||
@NotNull final TestableItem item) {
|
||||
REGISTRY.put(key, item);
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ public final class Items {
|
||||
/**
|
||||
* This is the backbone of the entire eco item system.
|
||||
* <p>
|
||||
* You can lookup a TestableItem for any material, custom item,
|
||||
* You can look up a TestableItem for any material, custom item,
|
||||
* or item in general, and it will return it with any modifiers
|
||||
* passed as parameters. This includes stack size (item amount)
|
||||
* and enchantments that should be present on the item.
|
||||
@@ -94,8 +94,8 @@ public final class Items {
|
||||
* <p>
|
||||
* The advantages of the testable item system are that there is the inbuilt
|
||||
* {@link TestableItem#matches(ItemStack)} - this allows to check if any item
|
||||
* is that testable item; which may sound negligible but actually it allows for
|
||||
* much more power an flexibility. For example, you can have an item with an
|
||||
* is that testable item; which may sound negligible, but actually it allows for
|
||||
* much more power and flexibility. For example, you can have an item with an
|
||||
* extra metadata tag, extra lore lines, different display name - and it
|
||||
* will still work as long as the test passes. This is very important
|
||||
* for custom crafting recipes where other plugins may add metadata
|
||||
@@ -104,6 +104,7 @@ public final class Items {
|
||||
* @param key The lookup string.
|
||||
* @return The testable item, or an {@link EmptyTestableItem}.
|
||||
*/
|
||||
@NotNull
|
||||
public static TestableItem lookup(@NotNull final String key) {
|
||||
if (key.contains("?")) {
|
||||
String[] options = key.split("\\?");
|
||||
@@ -235,6 +236,37 @@ public final class Items {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a Testable Item from an ItemStack.
|
||||
* <p>
|
||||
* Will search for registered items first. If there are no matches in the registry,
|
||||
* then it will return a {@link MaterialTestableItem} matching the item type.
|
||||
* <p>
|
||||
* Does not account for modifiers (arg parser data).
|
||||
*
|
||||
* @param item The ItemStack.
|
||||
* @return The found Testable Item.
|
||||
*/
|
||||
@NotNull
|
||||
public static TestableItem getItem(@Nullable final ItemStack item) {
|
||||
if (item == null || item.getType().isAir()) {
|
||||
return new EmptyTestableItem();
|
||||
}
|
||||
|
||||
CustomItem customItem = getCustomItem(item);
|
||||
|
||||
if (customItem != null) {
|
||||
return customItem;
|
||||
}
|
||||
|
||||
for (TestableItem known : REGISTRY.values()) {
|
||||
if (known.matches(item)) {
|
||||
return known;
|
||||
}
|
||||
}
|
||||
return new MaterialTestableItem(item.getType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if itemStack is a custom item.
|
||||
*
|
||||
@@ -284,6 +316,7 @@ public final class Items {
|
||||
* @param item The item.
|
||||
* @return The CustomItem.
|
||||
*/
|
||||
@NotNull
|
||||
public static CustomItem getOrWrap(@NotNull final TestableItem item) {
|
||||
if (item instanceof CustomItem) {
|
||||
return (CustomItem) item;
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.willfp.eco.core.items.args;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Parse leather armor colors.
|
||||
*
|
||||
* @deprecated Moved to internals.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public class ColorArgParser implements LookupArgParser {
|
||||
@Override
|
||||
public @Nullable Predicate<ItemStack> parseArguments(@NotNull final String[] args,
|
||||
@NotNull final ItemMeta meta) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -9,49 +9,14 @@ import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Parse custom model data.
|
||||
*
|
||||
* @deprecated Moved to internals.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public class CustomModelDataArgParser implements LookupArgParser {
|
||||
@Override
|
||||
public @Nullable Predicate<ItemStack> parseArguments(@NotNull final String[] args,
|
||||
@NotNull final ItemMeta meta) {
|
||||
Integer modelData = null;
|
||||
|
||||
for (String arg : args) {
|
||||
String[] argSplit = arg.split(":");
|
||||
if (!argSplit[0].equalsIgnoreCase("custom-model-data")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (argSplit.length < 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String asString = argSplit[1];
|
||||
|
||||
try {
|
||||
modelData = Integer.parseInt(asString);
|
||||
} catch (NumberFormatException e) {
|
||||
modelData = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (modelData == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
meta.setCustomModelData(modelData);
|
||||
|
||||
int finalModelData = modelData;
|
||||
return test -> {
|
||||
if (!test.hasItemMeta()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ItemMeta testMeta = test.getItemMeta();
|
||||
|
||||
assert testMeta != null;
|
||||
|
||||
return testMeta.getCustomModelData() == finalModelData;
|
||||
};
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,83 +1,22 @@
|
||||
package com.willfp.eco.core.items.args;
|
||||
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Parses enchantment arguments.
|
||||
*
|
||||
* @deprecated Moved to internals.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public class EnchantmentArgParser implements LookupArgParser {
|
||||
@Override
|
||||
public @Nullable Predicate<ItemStack> parseArguments(@NotNull final String[] args,
|
||||
@NotNull final ItemMeta meta) {
|
||||
Map<Enchantment, Integer> requiredEnchantments = new HashMap<>();
|
||||
|
||||
for (String enchantArg : args) {
|
||||
String[] enchantArgSplit = enchantArg.split(":");
|
||||
|
||||
Enchantment enchantment = Enchantment.getByKey(NamespacedKey.minecraft(enchantArgSplit[0].toLowerCase()));
|
||||
if (enchantment == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (enchantArgSplit.length < 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int level = Integer.parseInt(enchantArgSplit[1]);
|
||||
|
||||
requiredEnchantments.put(enchantment, level);
|
||||
}
|
||||
|
||||
if (requiredEnchantments.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (meta instanceof EnchantmentStorageMeta storageMeta) {
|
||||
requiredEnchantments.forEach((enchantment, integer) -> storageMeta.addStoredEnchant(enchantment, integer, true));
|
||||
} else {
|
||||
requiredEnchantments.forEach((enchantment, integer) -> meta.addEnchant(enchantment, integer, true));
|
||||
}
|
||||
|
||||
return test -> {
|
||||
if (!test.hasItemMeta()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ItemMeta testMeta = test.getItemMeta();
|
||||
|
||||
assert testMeta != null;
|
||||
|
||||
if (testMeta instanceof EnchantmentStorageMeta storageMeta) {
|
||||
for (Map.Entry<Enchantment, Integer> entry : requiredEnchantments.entrySet()) {
|
||||
if (!storageMeta.hasStoredEnchant(entry.getKey())) {
|
||||
return false;
|
||||
}
|
||||
if (storageMeta.getStoredEnchantLevel(entry.getKey()) < entry.getValue()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (Map.Entry<Enchantment, Integer> entry : requiredEnchantments.entrySet()) {
|
||||
if (!testMeta.hasEnchant(entry.getKey())) {
|
||||
return false;
|
||||
}
|
||||
if (testMeta.getEnchantLevel(entry.getKey()) < entry.getValue()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
package com.willfp.eco.core.items.args;
|
||||
|
||||
import com.willfp.eco.util.SkullUtils;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -11,49 +9,14 @@ import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Parse skull textures.
|
||||
*
|
||||
* @deprecated Moved to internals.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public class TextureArgParser implements LookupArgParser {
|
||||
@Override
|
||||
public @Nullable Predicate<ItemStack> parseArguments(@NotNull final String[] args,
|
||||
@NotNull final ItemMeta meta) {
|
||||
String skullTexture = null;
|
||||
|
||||
for (String arg : args) {
|
||||
String[] argSplit = arg.split(":");
|
||||
if (!argSplit[0].equalsIgnoreCase("texture")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (argSplit.length < 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
skullTexture = argSplit[1];
|
||||
}
|
||||
|
||||
if (meta instanceof SkullMeta skullMeta && skullTexture != null) {
|
||||
SkullUtils.setSkullTexture(skullMeta, skullTexture);
|
||||
}
|
||||
|
||||
if (skullTexture == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String finalSkullTexture = skullTexture;
|
||||
return test -> {
|
||||
if (!test.hasItemMeta()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ItemMeta testMeta = test.getItemMeta();
|
||||
|
||||
assert testMeta != null;
|
||||
|
||||
if (testMeta instanceof SkullMeta skullMeta) {
|
||||
return finalSkullTexture.equalsIgnoreCase(SkullUtils.getSkullTexture(skullMeta));
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.willfp.eco.core.recipe.recipes;
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.PluginDependent;
|
||||
import com.willfp.eco.core.Prerequisite;
|
||||
import com.willfp.eco.core.items.TestableItem;
|
||||
import com.willfp.eco.core.recipe.Recipes;
|
||||
import com.willfp.eco.core.recipe.parts.EmptyTestableItem;
|
||||
@@ -112,6 +113,12 @@ public final class ShapedCraftingRecipe extends PluginDependent<EcoPlugin> imple
|
||||
displayedRecipe.setIngredient(character, new RecipeChoice.ExactChoice(item));
|
||||
}
|
||||
|
||||
if (Prerequisite.HAS_1_18.isMet() && !Prerequisite.HAS_PAPER.isMet()) {
|
||||
if (Bukkit.getServer().getRecipe(this.getKey()) != null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Bukkit.getServer().addRecipe(shapedRecipe);
|
||||
Bukkit.getServer().addRecipe(displayedRecipe);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.willfp.eco.util;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -21,8 +20,8 @@ public final class ListUtils {
|
||||
* @return The list, filled will null objects.
|
||||
*/
|
||||
@NotNull
|
||||
public static <@Nullable T> List<List<T>> create2DList(final int rows,
|
||||
final int columns) {
|
||||
public static <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);
|
||||
|
||||
@@ -82,13 +82,12 @@ public final class PlayerUtils {
|
||||
* @return The player name.
|
||||
*/
|
||||
public static String getSavedDisplayName(@NotNull final OfflinePlayer player) {
|
||||
PlayerProfile profile = PlayerProfile.load(player);
|
||||
|
||||
if (player instanceof Player onlinePlayer) {
|
||||
profile.write(PLAYER_NAME_KEY, onlinePlayer.getDisplayName());
|
||||
return onlinePlayer.getDisplayName();
|
||||
updateSavedDisplayName(onlinePlayer);
|
||||
}
|
||||
|
||||
PlayerProfile profile = PlayerProfile.load(player);
|
||||
|
||||
String saved = profile.read(PLAYER_NAME_KEY);
|
||||
|
||||
if (saved.equals(PLAYER_NAME_KEY.getDefaultValue())) {
|
||||
|
||||
@@ -14,7 +14,7 @@ import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.Color;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@@ -4,7 +4,7 @@ buildscript {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31"
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,14 +16,14 @@ subprojects {
|
||||
|
||||
dependencies {
|
||||
compileOnly project(":eco-api")
|
||||
compileOnly 'org.jetbrains.kotlin:kotlin-stdlib:1.5.31'
|
||||
compileOnly 'org.jetbrains.kotlin:kotlin-stdlib:1.6.0'
|
||||
}
|
||||
|
||||
compileKotlin {
|
||||
kotlinOptions {
|
||||
jvmTarget = "16"
|
||||
jvmTarget = "17"
|
||||
}
|
||||
targetCompatibility = JavaVersion.VERSION_16
|
||||
sourceCompatibility = JavaVersion.VERSION_16
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,7 @@ open class EcoLoadableJSONConfig(
|
||||
}
|
||||
}
|
||||
|
||||
override fun createFile() {
|
||||
final override fun createFile() {
|
||||
val inputStream = source.getResourceAsStream(resourcePath)!!
|
||||
val outFile = File(this.plugin.dataFolder, resourcePath)
|
||||
val lastIndex = resourcePath.lastIndexOf('/')
|
||||
@@ -40,7 +40,7 @@ open class EcoLoadableJSONConfig(
|
||||
}
|
||||
if (!outFile.exists()) {
|
||||
val out: OutputStream = FileOutputStream(outFile)
|
||||
inputStream.copyTo(out, 1024)
|
||||
inputStream.copyTo(out)
|
||||
out.close()
|
||||
inputStream.close()
|
||||
}
|
||||
|
||||
@@ -40,11 +40,10 @@ open class EcoLoadableYamlConfig(
|
||||
}
|
||||
if (!outFile.exists()) {
|
||||
val out: OutputStream = FileOutputStream(outFile)
|
||||
inputStream.copyTo(out, 1024)
|
||||
inputStream.copyTo(out)
|
||||
out.close()
|
||||
inputStream.close()
|
||||
}
|
||||
plugin.configHandler.addConfig(this)
|
||||
}
|
||||
|
||||
override fun getResourcePath(): String {
|
||||
|
||||
@@ -5,12 +5,11 @@ import com.willfp.eco.util.StringUtils
|
||||
import org.bukkit.configuration.ConfigurationSection
|
||||
import org.bukkit.configuration.file.YamlConfiguration
|
||||
import java.io.StringReader
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
open class EcoYamlConfigWrapper<T : ConfigurationSection> : Config {
|
||||
lateinit var handle: T
|
||||
private val cache = ConcurrentHashMap<String, Any?>()
|
||||
private val cache = mutableMapOf<String, Any?>()
|
||||
|
||||
protected fun init(config: T): Config {
|
||||
handle = config
|
||||
@@ -70,9 +69,9 @@ open class EcoYamlConfigWrapper<T : ConfigurationSection> : Config {
|
||||
|
||||
override fun getInt(path: String): Int {
|
||||
return if (cache.containsKey(path)) {
|
||||
cache[path] as Int
|
||||
(cache[path] as Number).toInt()
|
||||
} else {
|
||||
cache[path] = handle.getInt(path, 0)
|
||||
cache[path] = handle.getDouble(path, 0.0).toInt()
|
||||
getInt(path)
|
||||
}
|
||||
}
|
||||
@@ -90,9 +89,9 @@ open class EcoYamlConfigWrapper<T : ConfigurationSection> : Config {
|
||||
def: Int
|
||||
): Int {
|
||||
return if (cache.containsKey(path)) {
|
||||
cache[path] as Int
|
||||
(cache[path] as Number).toInt()
|
||||
} else {
|
||||
cache[path] = handle.getInt(path, def)
|
||||
cache[path] = handle.getDouble(path, def.toDouble()).toInt()
|
||||
getInt(path)
|
||||
}
|
||||
}
|
||||
@@ -262,6 +261,31 @@ open class EcoYamlConfigWrapper<T : ConfigurationSection> : Config {
|
||||
}
|
||||
}
|
||||
|
||||
override fun getSubsections(path: String): MutableList<out Config> {
|
||||
return if (cache.containsKey(path)) {
|
||||
(cache[path] as Collection<Config>).toMutableList()
|
||||
} else {
|
||||
val mapList = ArrayList(handle.getMapList(path)) as List<Map<String, Any?>>
|
||||
val configList = mutableListOf<Config>()
|
||||
for (map in mapList) {
|
||||
val temp = YamlConfiguration.loadConfiguration(StringReader(""))
|
||||
temp.createSection("a", map)
|
||||
configList.add(EcoYamlConfigSection(temp.getConfigurationSection("a")!!))
|
||||
}
|
||||
|
||||
cache[path] = if (has(path)) configList else emptyList()
|
||||
getSubsections(path)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getSubsectionsOrNull(path: String): MutableList<out Config>? {
|
||||
return if (has(path)) {
|
||||
getSubsections(path)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
override fun clone(): Config {
|
||||
return EcoYamlConfigSection(
|
||||
YamlConfiguration.loadConfiguration(
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.willfp.eco.internal.drops.impl
|
||||
|
||||
import com.willfp.eco.core.drops.InternalDropQueue
|
||||
import com.willfp.eco.core.events.DropQueuePushEvent
|
||||
import com.willfp.eco.core.integrations.antigrief.AntigriefManager
|
||||
import com.willfp.eco.util.TelekinesisUtils
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.Location
|
||||
@@ -15,7 +17,7 @@ import org.bukkit.util.Vector
|
||||
open class EcoDropQueue(val player: Player) : InternalDropQueue {
|
||||
val items = mutableListOf<ItemStack>()
|
||||
var xp: Int = 0
|
||||
var loc: Location
|
||||
var location: Location
|
||||
var hasTelekinesis = false
|
||||
|
||||
override fun addItem(item: ItemStack): InternalDropQueue {
|
||||
@@ -34,7 +36,7 @@ open class EcoDropQueue(val player: Player) : InternalDropQueue {
|
||||
}
|
||||
|
||||
override fun setLocation(location: Location): InternalDropQueue {
|
||||
loc = location
|
||||
this.location = location
|
||||
return this
|
||||
}
|
||||
|
||||
@@ -47,8 +49,20 @@ open class EcoDropQueue(val player: Player) : InternalDropQueue {
|
||||
if (!hasTelekinesis) {
|
||||
hasTelekinesis = TelekinesisUtils.testPlayer(player)
|
||||
}
|
||||
val world = loc.world!!
|
||||
loc = loc.add(0.5, 0.5, 0.5)
|
||||
|
||||
if (hasTelekinesis && !AntigriefManager.canPickupItem(player, location)) {
|
||||
hasTelekinesis = false
|
||||
}
|
||||
|
||||
val pushEvent = DropQueuePushEvent(player, items, location, xp, hasTelekinesis)
|
||||
Bukkit.getServer().pluginManager.callEvent(pushEvent)
|
||||
|
||||
if (pushEvent.isCancelled) {
|
||||
return
|
||||
}
|
||||
|
||||
val world = location.world!!
|
||||
location = location.add(0.5, 0.5, 0.5)
|
||||
items.removeIf { itemStack: ItemStack -> itemStack.type == Material.AIR }
|
||||
if (items.isEmpty()) {
|
||||
return
|
||||
@@ -56,7 +70,7 @@ open class EcoDropQueue(val player: Player) : InternalDropQueue {
|
||||
if (hasTelekinesis) {
|
||||
val leftover = player.inventory.addItem(*items.toTypedArray())
|
||||
for (drop in leftover.values) {
|
||||
world.dropItem(loc, drop!!).velocity = Vector()
|
||||
world.dropItem(location, drop!!).velocity = Vector()
|
||||
}
|
||||
if (xp > 0) {
|
||||
val event = PlayerExpChangeEvent(player, xp)
|
||||
@@ -68,16 +82,16 @@ open class EcoDropQueue(val player: Player) : InternalDropQueue {
|
||||
}
|
||||
} else {
|
||||
for (drop in items) {
|
||||
world.dropItem(loc, drop).velocity = Vector()
|
||||
world.dropItem(location, drop).velocity = Vector()
|
||||
}
|
||||
if (xp > 0) {
|
||||
val orb = world.spawnEntity(loc, EntityType.EXPERIENCE_ORB) as ExperienceOrb
|
||||
val orb = world.spawnEntity(location, EntityType.EXPERIENCE_ORB) as ExperienceOrb
|
||||
orb.experience = xp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
loc = player.location
|
||||
location = player.location
|
||||
}
|
||||
}
|
||||
@@ -10,10 +10,10 @@ class EcoFastCollatedDropQueue(player: Player) : EcoDropQueue(player) {
|
||||
val fetched = COLLATED_MAP[player]
|
||||
|
||||
if (fetched == null) {
|
||||
COLLATED_MAP[player] = CollatedDrops(items, loc, xp, hasTelekinesis)
|
||||
COLLATED_MAP[player] = CollatedDrops(items, location, xp, hasTelekinesis)
|
||||
} else {
|
||||
fetched.addDrops(items)
|
||||
fetched.location = loc
|
||||
fetched.location = location
|
||||
fetched.addXp(xp)
|
||||
if (this.hasTelekinesis) {
|
||||
fetched.forceTelekinesis()
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.willfp.eco.internal.gui.menu
|
||||
|
||||
import com.willfp.eco.internal.gui.slot.EcoCaptivatorSlot
|
||||
import com.willfp.eco.util.MenuUtils
|
||||
import com.willfp.eco.util.StringUtils
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.NamespacedKey
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.inventory.Inventory
|
||||
@@ -20,12 +20,14 @@ class ExtendedInventory(
|
||||
for (i in 0 until inventory.size) {
|
||||
val (row, column) = MenuUtils.convertSlotToRowColumn(i)
|
||||
val slot = menu.getSlot(row, column)
|
||||
if (slot is EcoCaptivatorSlot) {
|
||||
if (slot.isCaptive) {
|
||||
val defaultItem = slot.getItemStack(player)
|
||||
val item = inventory.getItem(i) ?: continue
|
||||
if (item != defaultItem) {
|
||||
captiveItems.add(item)
|
||||
if (item == defaultItem && item.type == Material.AIR) {
|
||||
continue
|
||||
}
|
||||
|
||||
captiveItems.add(item)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
package com.willfp.eco.internal.gui.slot
|
||||
|
||||
import com.willfp.eco.core.Eco
|
||||
import com.willfp.eco.core.gui.slot.functional.SlotHandler
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
class EcoCaptivatorSlot : EcoSlot(
|
||||
{ _, _ -> ItemStack(Material.AIR) },
|
||||
allowMovingItem,
|
||||
allowMovingItem,
|
||||
allowMovingItem,
|
||||
allowMovingItem,
|
||||
allowMovingItem,
|
||||
{ _, _, _ -> }
|
||||
) {
|
||||
companion object {
|
||||
val plugin = Eco.getHandler().ecoPlugin
|
||||
|
||||
val allowMovingItem = SlotHandler { event, _, _ ->
|
||||
event.isCancelled = false
|
||||
}
|
||||
}
|
||||
|
||||
override fun isCaptive(): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.willfp.eco.internal.gui.slot
|
||||
|
||||
import com.willfp.eco.core.gui.slot.functional.SlotHandler
|
||||
import com.willfp.eco.core.gui.slot.functional.SlotProvider
|
||||
|
||||
class EcoCaptiveSlot(
|
||||
provider: SlotProvider
|
||||
) : EcoSlot(
|
||||
provider,
|
||||
allowMovingItem,
|
||||
allowMovingItem,
|
||||
allowMovingItem,
|
||||
allowMovingItem,
|
||||
allowMovingItem,
|
||||
{ _, _, _ -> }
|
||||
) {
|
||||
override fun isCaptive(): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
private val allowMovingItem = SlotHandler { event, _, _ ->
|
||||
event.isCancelled = false
|
||||
}
|
||||
@@ -31,8 +31,7 @@ open class EcoSlot(
|
||||
ClickType.SHIFT_LEFT -> this.onShiftLeftClick.handle(event, this, menu)
|
||||
ClickType.SHIFT_RIGHT -> this.onShiftRightClick.handle(event, this, menu)
|
||||
ClickType.MIDDLE -> this.onMiddleClick.handle(event, this, menu)
|
||||
else -> {
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ class EcoSlotBuilder(private val provider: SlotProvider) : SlotBuilder {
|
||||
|
||||
override fun build(): Slot {
|
||||
return if (captive) {
|
||||
EcoCaptivatorSlot()
|
||||
EcoCaptiveSlot(provider)
|
||||
} else {
|
||||
EcoSlot(provider, onLeftClick, onRightClick, onShiftLeftClick, onShiftRightClick, onMiddleClick, modifier)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.willfp.eco.internal.items
|
||||
|
||||
import com.willfp.eco.core.items.args.LookupArgParser
|
||||
import org.bukkit.Color
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.inventory.meta.ItemMeta
|
||||
import org.bukkit.inventory.meta.LeatherArmorMeta
|
||||
import java.util.function.Predicate
|
||||
|
||||
class ArgParserColor : LookupArgParser {
|
||||
override fun parseArguments(args: Array<out String>, meta: ItemMeta): Predicate<ItemStack>? {
|
||||
if (meta !is LeatherArmorMeta) {
|
||||
return null
|
||||
}
|
||||
|
||||
var color: String? = null
|
||||
|
||||
for (arg in args) {
|
||||
val argSplit = arg.split(":")
|
||||
if (!argSplit[0].equals("color", ignoreCase = true)) {
|
||||
continue
|
||||
}
|
||||
if (argSplit.size < 2) {
|
||||
continue
|
||||
}
|
||||
color = argSplit[1].replace("#","")
|
||||
}
|
||||
|
||||
color ?: return null
|
||||
|
||||
meta.setColor(Color.fromRGB(Integer.parseInt(color, 16)))
|
||||
|
||||
return Predicate {
|
||||
val testMeta = it.itemMeta as? LeatherArmorMeta ?: return@Predicate false
|
||||
|
||||
color.equals(
|
||||
Integer.toHexString(testMeta.color.red)
|
||||
+ Integer.toHexString(testMeta.color.green)
|
||||
+ Integer.toHexString(testMeta.color.blue),
|
||||
ignoreCase = true
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.willfp.eco.internal.items
|
||||
|
||||
import com.willfp.eco.core.items.args.LookupArgParser
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.inventory.meta.ItemMeta
|
||||
import java.util.function.Predicate
|
||||
|
||||
class ArgParserCustomModelData : LookupArgParser {
|
||||
override fun parseArguments(args: Array<out String>, meta: ItemMeta): Predicate<ItemStack>? {
|
||||
var modelData: Int? = null
|
||||
|
||||
for (arg in args) {
|
||||
val argSplit = arg.split(":")
|
||||
if (!argSplit[0].equals("custom-model-data", ignoreCase = true)) {
|
||||
continue
|
||||
}
|
||||
if (argSplit.size < 2) {
|
||||
continue
|
||||
}
|
||||
modelData = argSplit[1].toIntOrNull()
|
||||
}
|
||||
|
||||
modelData ?: return null
|
||||
|
||||
meta.setCustomModelData(modelData)
|
||||
|
||||
return Predicate {
|
||||
val testMeta = it.itemMeta ?: return@Predicate false
|
||||
|
||||
testMeta.customModelData == modelData
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.willfp.eco.internal.items
|
||||
|
||||
import com.willfp.eco.core.fast.FastItemStack
|
||||
import com.willfp.eco.core.items.args.LookupArgParser
|
||||
import org.bukkit.NamespacedKey
|
||||
import org.bukkit.enchantments.Enchantment
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.inventory.meta.EnchantmentStorageMeta
|
||||
import org.bukkit.inventory.meta.ItemMeta
|
||||
import java.util.function.Predicate
|
||||
|
||||
class ArgParserEnchantment : LookupArgParser {
|
||||
override fun parseArguments(args: Array<out String>, meta: ItemMeta): Predicate<ItemStack>? {
|
||||
val enchants = mutableMapOf<Enchantment, Int>()
|
||||
|
||||
for (arg in args) {
|
||||
val argSplit = arg.split(":")
|
||||
|
||||
if (argSplit.size < 2) {
|
||||
continue
|
||||
}
|
||||
|
||||
val enchant = Enchantment.getByKey(NamespacedKey.minecraft(argSplit[0].lowercase()))
|
||||
val level = argSplit[1].toIntOrNull()
|
||||
|
||||
if (enchant != null && level != null) {
|
||||
enchants[enchant] = level
|
||||
}
|
||||
}
|
||||
|
||||
if (enchants.isEmpty()) {
|
||||
return null
|
||||
}
|
||||
|
||||
for ((enchant, level) in enchants) {
|
||||
if (meta is EnchantmentStorageMeta) {
|
||||
meta.addStoredEnchant(enchant, level, true)
|
||||
} else {
|
||||
meta.addEnchant(enchant, level, true)
|
||||
}
|
||||
}
|
||||
|
||||
return Predicate {
|
||||
val onItem = FastItemStack.wrap(it).getEnchantmentsOnItem(true)
|
||||
|
||||
for ((enchant, level) in enchants) {
|
||||
if ((onItem[enchant] ?: 0) < level) {
|
||||
return@Predicate false
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.willfp.eco.internal.items
|
||||
|
||||
import com.willfp.eco.core.items.args.LookupArgParser
|
||||
import org.bukkit.inventory.ItemFlag
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.inventory.meta.ItemMeta
|
||||
import java.util.function.Predicate
|
||||
|
||||
class ArgParserFlag : LookupArgParser {
|
||||
override fun parseArguments(args: Array<out String>, meta: ItemMeta): Predicate<ItemStack>? {
|
||||
val flags = mutableSetOf<ItemFlag>()
|
||||
|
||||
for (arg in args) {
|
||||
val flag = try {
|
||||
ItemFlag.valueOf(arg.uppercase())
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
} ?: continue
|
||||
|
||||
flags.add(flag)
|
||||
}
|
||||
|
||||
if (flags.isEmpty()) {
|
||||
return null
|
||||
}
|
||||
|
||||
meta.addItemFlags(*flags.toTypedArray())
|
||||
|
||||
return Predicate {
|
||||
val testMeta = it.itemMeta ?: return@Predicate false
|
||||
|
||||
testMeta.itemFlags.containsAll(flags)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.willfp.eco.internal.items
|
||||
|
||||
import com.willfp.eco.core.items.args.LookupArgParser
|
||||
import com.willfp.eco.util.StringUtils
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.inventory.meta.ItemMeta
|
||||
import java.util.function.Predicate
|
||||
|
||||
class ArgParserName : LookupArgParser {
|
||||
override fun parseArguments(args: Array<out String>, meta: ItemMeta): Predicate<ItemStack>? {
|
||||
var name: String? = null
|
||||
|
||||
for (arg in args) {
|
||||
val argSplit = arg.split(":")
|
||||
if (!argSplit[0].equals("name", ignoreCase = true)) {
|
||||
continue
|
||||
}
|
||||
if (argSplit.size < 2) {
|
||||
continue
|
||||
}
|
||||
name = argSplit[1].replace("_", "")
|
||||
}
|
||||
|
||||
name ?: return null
|
||||
|
||||
val formatted = StringUtils.format(name)
|
||||
|
||||
meta.setDisplayName(formatted)
|
||||
|
||||
return Predicate {
|
||||
val testMeta = it.itemMeta ?: return@Predicate false
|
||||
|
||||
testMeta.displayName == formatted
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.willfp.eco.internal.items
|
||||
|
||||
import com.willfp.eco.core.items.args.LookupArgParser
|
||||
import com.willfp.eco.util.SkullUtils
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.inventory.meta.ItemMeta
|
||||
import org.bukkit.inventory.meta.SkullMeta
|
||||
import java.util.function.Predicate
|
||||
|
||||
class ArgParserTexture : LookupArgParser {
|
||||
override fun parseArguments(args: Array<out String>, meta: ItemMeta): Predicate<ItemStack>? {
|
||||
if (meta !is SkullMeta) {
|
||||
return null
|
||||
}
|
||||
|
||||
var texture: String? = null
|
||||
|
||||
for (arg in args) {
|
||||
val argSplit = arg.split(":")
|
||||
if (!argSplit[0].equals("texture", ignoreCase = true)) {
|
||||
continue
|
||||
}
|
||||
if (argSplit.size < 2) {
|
||||
continue
|
||||
}
|
||||
texture = argSplit[1]
|
||||
}
|
||||
|
||||
texture ?: return null
|
||||
|
||||
SkullUtils.setSkullTexture(meta, texture)
|
||||
|
||||
return Predicate {
|
||||
val testMeta = it.itemMeta as? SkullMeta ?: return@Predicate false
|
||||
|
||||
texture == SkullUtils.getSkullTexture(testMeta)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.willfp.eco.internal.items
|
||||
|
||||
import com.willfp.eco.core.items.args.LookupArgParser
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.inventory.meta.ItemMeta
|
||||
import java.util.function.Predicate
|
||||
|
||||
class ArgParserUnbreakable : LookupArgParser {
|
||||
override fun parseArguments(args: Array<out String>, meta: ItemMeta): Predicate<ItemStack>? {
|
||||
var unbreakable = false
|
||||
|
||||
for (arg in args) {
|
||||
if (arg.equals("unbreakable", true)) {
|
||||
unbreakable = true
|
||||
}
|
||||
}
|
||||
|
||||
if (!unbreakable) {
|
||||
return null
|
||||
}
|
||||
|
||||
meta.isUnbreakable = true
|
||||
|
||||
return Predicate {
|
||||
val testMeta = it.itemMeta ?: return@Predicate false
|
||||
|
||||
testMeta.isUnbreakable
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,7 +74,8 @@ class EcoProxyFactory(
|
||||
companion object {
|
||||
val SUPPORTED_VERSIONS = listOf(
|
||||
"v1_16_R3",
|
||||
"v1_17_R1"
|
||||
"v1_17_R1",
|
||||
"v1_18_R1"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,6 @@ class RequirementPlaceholderGreaterThan : Requirement() {
|
||||
|
||||
val placeholder = args[0]
|
||||
val equals = args[1].toDoubleOrNull() ?: return false
|
||||
return PlaceholderManager.translatePlaceholders(placeholder, player).toDoubleOrNull() ?: 0.0 >= equals
|
||||
return (PlaceholderManager.translatePlaceholders(placeholder, player).toDoubleOrNull() ?: 0.0) >= equals
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,6 @@ class RequirementPlaceholderLessThan : Requirement() {
|
||||
|
||||
val placeholder = args[0]
|
||||
val equals = args[1].toDoubleOrNull() ?: return false
|
||||
return PlaceholderManager.translatePlaceholders(placeholder, player).toDoubleOrNull() ?: 0.0 < equals
|
||||
return (PlaceholderManager.translatePlaceholders(placeholder, player).toDoubleOrNull() ?: 0.0) < equals
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
group 'com.willfp'
|
||||
version rootProject.version
|
||||
|
||||
subprojects {
|
||||
dependencies {
|
||||
compileOnly project(':eco-core:core-proxy')
|
||||
compileOnly project(':eco-core:core-plugin')
|
||||
compileOnly project(':eco-core:core-backend')
|
||||
}
|
||||
}
|
||||
12
eco-core/core-nms/build.gradle.kts
Normal file
12
eco-core/core-nms/build.gradle.kts
Normal file
@@ -0,0 +1,12 @@
|
||||
group = "com.willfp"
|
||||
version = rootProject.version
|
||||
|
||||
subprojects {
|
||||
dependencies {
|
||||
compileOnly(project(":eco-core:core-proxy"))
|
||||
compileOnly(project(":eco-core:core-plugin"))
|
||||
compileOnly(project(":eco-core:core-backend"))
|
||||
// libraries.minecraft.net machine broke
|
||||
compileOnly("com.github.Mojang:brigadier:1.0.18")
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,4 @@ version rootProject.version
|
||||
|
||||
dependencies {
|
||||
compileOnly 'org.spigotmc:spigot:1.16.5-R0.1-SNAPSHOT'
|
||||
compileOnly 'net.kyori:adventure-api:4.9.1'
|
||||
compileOnly 'net.kyori:adventure-text-serializer-gson:4.8.1'
|
||||
}
|
||||
@@ -165,7 +165,7 @@ class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemS
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return handle.tag?.hashCode() ?: 0b00010101 * 31 + Item.getId(handle.item)
|
||||
return handle.tag?.hashCode() ?: (0b00010101 * 31 + Item.getId(handle.item))
|
||||
}
|
||||
|
||||
private fun apply() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id("io.papermc.paperweight.userdev") version "1.1.14"
|
||||
id("io.papermc.paperweight.userdev") version "1.2.0"
|
||||
}
|
||||
|
||||
group = "com.willfp"
|
||||
@@ -7,8 +7,6 @@ version = rootProject.version
|
||||
|
||||
dependencies {
|
||||
paperDevBundle("1.17.1-R0.1-SNAPSHOT")
|
||||
compileOnly("net.kyori:adventure-api:4.9.1")
|
||||
compileOnly("net.kyori:adventure-text-serializer-gson:4.8.1")
|
||||
}
|
||||
|
||||
tasks {
|
||||
|
||||
@@ -180,7 +180,7 @@ class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemS
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return handle.tag?.hashCode() ?: 0b00010101 * 31 + Item.getId(handle.item)
|
||||
return handle.tag?.hashCode() ?: (0b00010101 * 31 + Item.getId(handle.item))
|
||||
}
|
||||
|
||||
private fun apply() {
|
||||
|
||||
6
eco-core/core-nms/v1_18_R1/build.gradle.kts
Normal file
6
eco-core/core-nms/v1_18_R1/build.gradle.kts
Normal file
@@ -0,0 +1,6 @@
|
||||
group = "com.willfp"
|
||||
version = rootProject.version
|
||||
|
||||
dependencies {
|
||||
implementation(files("./impl.jar"))
|
||||
}
|
||||
BIN
eco-core/core-nms/v1_18_R1/impl.jar
Normal file
BIN
eco-core/core-nms/v1_18_R1/impl.jar
Normal file
Binary file not shown.
@@ -2,14 +2,10 @@ group 'com.willfp'
|
||||
version rootProject.version
|
||||
|
||||
dependencies {
|
||||
implementation 'org.bstats:bstats-bukkit:1.7'
|
||||
implementation('net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT') {
|
||||
exclude group: 'net.kyori', module: 'adventure-api'
|
||||
}
|
||||
compileOnly 'net.kyori:adventure-platform-bukkit:4.0.0'
|
||||
compileOnly 'net.kyori:adventure-api:4.9.2'
|
||||
compileOnly 'net.kyori:adventure-text-serializer-gson:4.9.2'
|
||||
compileOnly 'net.kyori:adventure-text-serializer-legacy:4.9.2'
|
||||
compileOnly 'org.apache.maven:maven-artifact:3.8.1'
|
||||
compileOnly 'com.google.code.gson:gson:2.8.8'
|
||||
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
|
||||
@@ -42,6 +38,8 @@ dependencies {
|
||||
compileOnly 'com.google.guava:guava:31.0.1-jre'
|
||||
compileOnly 'com.iridium:IridiumSkyblock:3.1.2'
|
||||
compileOnly 'com.github.WillFP:CrashClaim:1.0.19'
|
||||
compileOnly 'com.wolfyscript.wolfyutilities:wolfyutilities:1.7.8.1'
|
||||
compileOnly 'com.github.decentsoftware-eu:decentholograms:2.1.2'
|
||||
|
||||
// CombatLogX V10 + NewbieHelper Expansion
|
||||
compileOnly 'com.SirBlobman.combatlogx:CombatLogX-API:10.0.0.0-SNAPSHOT'
|
||||
|
||||
@@ -118,7 +118,7 @@ class EcoHandler : com.willfp.eco.internal.spigot.EcoSpigotPlugin(), Handler {
|
||||
}
|
||||
|
||||
override fun registerBStats(plugin: EcoPlugin) {
|
||||
MetricHandler.createMetrics(plugin, this.ecoPlugin)
|
||||
MetricHandler.createMetrics(plugin)
|
||||
}
|
||||
|
||||
override fun getRequirementFactory(): EcoRequirementFactory {
|
||||
|
||||
@@ -15,17 +15,22 @@ import com.willfp.eco.core.integrations.hologram.HologramManager
|
||||
import com.willfp.eco.core.integrations.mcmmo.McmmoManager
|
||||
import com.willfp.eco.core.integrations.shop.ShopManager
|
||||
import com.willfp.eco.core.items.Items
|
||||
import com.willfp.eco.core.items.args.CustomModelDataArgParser
|
||||
import com.willfp.eco.core.items.args.EnchantmentArgParser
|
||||
import com.willfp.eco.core.items.args.TextureArgParser
|
||||
import com.willfp.eco.internal.display.EcoDisplayHandler
|
||||
import com.willfp.eco.internal.drops.DropManager
|
||||
import com.willfp.eco.internal.items.ArgParserColor
|
||||
import com.willfp.eco.internal.items.ArgParserCustomModelData
|
||||
import com.willfp.eco.internal.items.ArgParserEnchantment
|
||||
import com.willfp.eco.internal.items.ArgParserFlag
|
||||
import com.willfp.eco.internal.items.ArgParserName
|
||||
import com.willfp.eco.internal.items.ArgParserTexture
|
||||
import com.willfp.eco.internal.items.ArgParserUnbreakable
|
||||
import com.willfp.eco.internal.spigot.arrows.ArrowDataListener
|
||||
import com.willfp.eco.internal.spigot.data.DataListener
|
||||
import com.willfp.eco.internal.spigot.data.PlayerBlockListener
|
||||
import com.willfp.eco.internal.spigot.data.storage.ProfileSaver
|
||||
import com.willfp.eco.internal.spigot.display.PacketAutoRecipe
|
||||
import com.willfp.eco.internal.spigot.display.PacketChat
|
||||
import com.willfp.eco.internal.spigot.display.PacketHeldWindowItems
|
||||
import com.willfp.eco.internal.spigot.display.PacketOpenWindowMerchant
|
||||
import com.willfp.eco.internal.spigot.display.PacketSetCreativeSlot
|
||||
import com.willfp.eco.internal.spigot.display.PacketSetSlot
|
||||
@@ -64,6 +69,7 @@ import com.willfp.eco.internal.spigot.integrations.customitems.CustomItemsItemsA
|
||||
import com.willfp.eco.internal.spigot.integrations.customitems.CustomItemsOraxen
|
||||
import com.willfp.eco.internal.spigot.integrations.economy.EconomyVault
|
||||
import com.willfp.eco.internal.spigot.integrations.hologram.HologramCMI
|
||||
import com.willfp.eco.internal.spigot.integrations.hologram.HologramDecentHolograms
|
||||
import com.willfp.eco.internal.spigot.integrations.hologram.HologramHolographicDisplays
|
||||
import com.willfp.eco.internal.spigot.integrations.mcmmo.McmmoIntegrationImpl
|
||||
import com.willfp.eco.internal.spigot.integrations.multiverseinventories.MultiverseInventoriesIntegration
|
||||
@@ -90,9 +96,13 @@ abstract class EcoSpigotPlugin : EcoPlugin(
|
||||
"&a"
|
||||
) {
|
||||
init {
|
||||
Items.registerArgParser(EnchantmentArgParser())
|
||||
Items.registerArgParser(TextureArgParser())
|
||||
Items.registerArgParser(CustomModelDataArgParser())
|
||||
Items.registerArgParser(ArgParserEnchantment())
|
||||
Items.registerArgParser(ArgParserColor())
|
||||
Items.registerArgParser(ArgParserTexture())
|
||||
Items.registerArgParser(ArgParserCustomModelData())
|
||||
Items.registerArgParser(ArgParserFlag())
|
||||
Items.registerArgParser(ArgParserUnbreakable())
|
||||
Items.registerArgParser(ArgParserName())
|
||||
|
||||
val skullProxy = getProxy(SkullProxy::class.java)
|
||||
SkullUtils.initialize(
|
||||
@@ -209,6 +219,7 @@ abstract class EcoSpigotPlugin : EcoPlugin(
|
||||
// Hologram
|
||||
IntegrationLoader("HolographicDisplays") { HologramManager.register(HologramHolographicDisplays(this)) },
|
||||
IntegrationLoader("CMI") { HologramManager.register(HologramCMI()) },
|
||||
IntegrationLoader("DecentHolograms") { HologramManager.register(HologramDecentHolograms()) },
|
||||
//IntegrationLoader("GHolo") { HologramManager.register(HologramGHolo()) },
|
||||
|
||||
// AFK
|
||||
@@ -240,6 +251,7 @@ abstract class EcoSpigotPlugin : EcoPlugin(
|
||||
PacketSetCreativeSlot(this),
|
||||
PacketSetSlot(this),
|
||||
PacketWindowItems(this),
|
||||
PacketHeldWindowItems(this),
|
||||
PacketOpenWindowMerchant(this)
|
||||
)
|
||||
}
|
||||
@@ -254,7 +266,7 @@ abstract class EcoSpigotPlugin : EcoPlugin(
|
||||
GUIListener(this),
|
||||
ArrowDataListener(this),
|
||||
ArmorChangeEventListeners(this),
|
||||
DataListener(),
|
||||
DataListener(this),
|
||||
PlayerBlockListener(this)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.willfp.eco.internal.spigot.data
|
||||
|
||||
import com.willfp.eco.core.Eco
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.util.PlayerUtils
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.Listener
|
||||
@@ -8,16 +9,19 @@ import org.bukkit.event.player.PlayerJoinEvent
|
||||
import org.bukkit.event.player.PlayerLoginEvent
|
||||
import org.bukkit.event.player.PlayerQuitEvent
|
||||
|
||||
class DataListener : Listener {
|
||||
class DataListener(
|
||||
private val plugin: EcoPlugin
|
||||
) : Listener {
|
||||
@EventHandler
|
||||
fun onLeave(event: PlayerQuitEvent) {
|
||||
PlayerUtils.updateSavedDisplayName(event.player)
|
||||
Eco.getHandler().playerProfileHandler.unloadPlayer(event.player.uniqueId)
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
fun onJoin(event: PlayerJoinEvent) {
|
||||
PlayerUtils.updateSavedDisplayName(event.player)
|
||||
plugin.scheduler.runLater({
|
||||
PlayerUtils.updateSavedDisplayName(event.player)
|
||||
}, 5)
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.jetbrains.exposed.sql.select
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import org.jetbrains.exposed.sql.update
|
||||
import java.util.UUID
|
||||
import java.util.concurrent.Callable
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
@@ -114,13 +115,21 @@ class MySQLDataHandler(
|
||||
}
|
||||
|
||||
override fun <T> read(uuid: UUID, key: NamespacedKey): T? {
|
||||
var value: T? = null
|
||||
transaction {
|
||||
val player = getPlayer(uuid)
|
||||
value = player[getColumn(key.toString())] as T?
|
||||
val doRead = Callable<T?> {
|
||||
var value: T? = null
|
||||
transaction {
|
||||
val player = getPlayer(uuid)
|
||||
value = player[getColumn(key.toString())] as T?
|
||||
}
|
||||
|
||||
return@Callable value
|
||||
}
|
||||
|
||||
return value
|
||||
return if (Eco.getHandler().ecoPlugin.configYml.getBool("mysql.async-reads")) {
|
||||
executor.submit(doRead).get()
|
||||
} else {
|
||||
doRead.call()
|
||||
}
|
||||
}
|
||||
|
||||
object Players : UUIDTable("eco_players")
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.willfp.eco.internal.spigot.display
|
||||
|
||||
import com.comphenix.protocol.PacketType
|
||||
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.core.Prerequisite
|
||||
import com.willfp.eco.core.display.Display
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
class PacketHeldWindowItems(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, PacketType.Play.Server.WINDOW_ITEMS, false) {
|
||||
override fun onSend(
|
||||
packet: PacketContainer,
|
||||
player: Player,
|
||||
event: PacketEvent
|
||||
) {
|
||||
if (!Prerequisite.HAS_1_17.isMet) {
|
||||
return
|
||||
}
|
||||
|
||||
packet.itemModifier.modify(0) { item: ItemStack? ->
|
||||
Display.display(
|
||||
item!!, player
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,6 +57,11 @@ class AntigriefBentoBox : AntigriefWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
override fun canPickupItem(player: Player, location: Location): Boolean {
|
||||
val island = BentoBox.getInstance().islandsManager.getIslandAt(location).orElse(null) ?: return true
|
||||
return island.isAllowed(User.getInstance(player), Flags.ITEM_PICKUP)
|
||||
}
|
||||
|
||||
override fun getPluginName(): String {
|
||||
return "BentoBox"
|
||||
}
|
||||
|
||||
@@ -55,6 +55,10 @@ class AntigriefCombatLogXV10 : AntigriefWrapper {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun canPickupItem(player: Player, location: Location): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun getPluginName(): String {
|
||||
return "CombatLogX"
|
||||
}
|
||||
|
||||
@@ -58,6 +58,10 @@ class AntigriefCombatLogXV11 : AntigriefWrapper {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun canPickupItem(player: Player, location: Location): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun getPluginName(): String {
|
||||
return "CombatLogX"
|
||||
}
|
||||
|
||||
@@ -48,6 +48,10 @@ class AntigriefCrashClaim : AntigriefWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
override fun canPickupItem(player: Player, location: Location): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun getPluginName(): String {
|
||||
return "CrashClaim"
|
||||
}
|
||||
|
||||
@@ -31,4 +31,8 @@ class AntigriefDeluxeCombat: AntigriefWrapper {
|
||||
else -> true
|
||||
}
|
||||
}
|
||||
|
||||
override fun canPickupItem(player: Player, location: Location): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -65,6 +65,10 @@ class AntigriefFactionsUUID : AntigriefWrapper {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun canPickupItem(player: Player, location: Location): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun getPluginName(): String {
|
||||
return "FactionsUUID"
|
||||
}
|
||||
|
||||
@@ -51,6 +51,10 @@ class AntigriefGriefPrevention : AntigriefWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
override fun canPickupItem(player: Player, location: Location): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun getPluginName(): String {
|
||||
return "GriefPrevention"
|
||||
}
|
||||
|
||||
@@ -48,6 +48,11 @@ class AntigriefIridiumSkyblock : AntigriefWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
override fun canPickupItem(player: Player, location: Location): Boolean {
|
||||
val api = IridiumSkyblockAPI.getInstance() ?: return true
|
||||
return api.getIslandPermission(api.getIslandViaLocation(location).orElse(null) ?: return true, api.getUser(player), PermissionType.PICKUP_ITEMS)
|
||||
}
|
||||
|
||||
override fun getPluginName(): String {
|
||||
return "IridiumSkyblock"
|
||||
}
|
||||
|
||||
@@ -65,6 +65,10 @@ class AntigriefKingdoms : AntigriefWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
override fun canPickupItem(player: Player, location: Location): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun getPluginName(): String {
|
||||
return "Kingdoms"
|
||||
}
|
||||
|
||||
@@ -52,6 +52,11 @@ class AntigriefLands(private val plugin: EcoPlugin) : AntigriefWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
override fun canPickupItem(player: Player, location: Location): Boolean {
|
||||
val area = landsIntegration.getAreaByLoc(location) ?: return true
|
||||
return area.hasFlag(player, Flags.ITEM_PICKUP, false)
|
||||
}
|
||||
|
||||
override fun getPluginName(): String {
|
||||
return "Lands"
|
||||
}
|
||||
|
||||
@@ -2,11 +2,12 @@ package com.willfp.eco.internal.spigot.integrations.antigrief
|
||||
|
||||
import com.bgsoftware.superiorskyblock.api.SuperiorSkyblockAPI
|
||||
import com.bgsoftware.superiorskyblock.api.enums.HitActionResult
|
||||
import com.bgsoftware.superiorskyblock.api.island.Island
|
||||
import com.bgsoftware.superiorskyblock.api.island.IslandPrivilege
|
||||
import com.bgsoftware.superiorskyblock.api.wrappers.SuperiorPlayer
|
||||
import com.willfp.eco.core.integrations.antigrief.AntigriefWrapper
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.block.Block
|
||||
import org.bukkit.entity.Animals
|
||||
import org.bukkit.entity.LivingEntity
|
||||
import org.bukkit.entity.Monster
|
||||
import org.bukkit.entity.Player
|
||||
@@ -17,11 +18,27 @@ class AntigriefSuperiorSkyblock2 : AntigriefWrapper {
|
||||
}
|
||||
|
||||
override fun canBreakBlock(player: Player, block: Block): Boolean {
|
||||
if (SuperiorSkyblockAPI.getPlayer(player).hasBypassModeEnabled()) {
|
||||
val island = SuperiorSkyblockAPI.getIslandAt(block.location)
|
||||
val superiorPlayer = SuperiorSkyblockAPI.getPlayer(player)
|
||||
|
||||
if (island == null) {
|
||||
if (!superiorPlayer.hasBypassModeEnabled() && SuperiorSkyblockAPI.getSuperiorSkyblock().grid
|
||||
.isIslandsWorld(superiorPlayer.world)
|
||||
) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
return SuperiorSkyblockAPI.getPlayer(player).hasPermission(IslandPrivilege.getByName("Break"))
|
||||
|| SuperiorSkyblockAPI.getPlayer(player).hasPermission(IslandPrivilege.getByName("BREAK"))
|
||||
|
||||
if (!island.hasPermission(superiorPlayer, IslandPrivilege.getByName("BREAK"))) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (!island.isInsideRange(block.location)) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun canCreateExplosion(player: Player, location: Location): Boolean {
|
||||
@@ -32,26 +49,52 @@ class AntigriefSuperiorSkyblock2 : AntigriefWrapper {
|
||||
}
|
||||
|
||||
override fun canPlaceBlock(player: Player, block: Block): Boolean {
|
||||
if (SuperiorSkyblockAPI.getPlayer(player).hasBypassModeEnabled()) {
|
||||
val island = SuperiorSkyblockAPI.getIslandAt(block.location)
|
||||
val superiorPlayer: SuperiorPlayer = SuperiorSkyblockAPI.getPlayer(player)
|
||||
|
||||
if (island == null) {
|
||||
if (!superiorPlayer.hasBypassModeEnabled() && SuperiorSkyblockAPI.getSuperiorSkyblock().grid
|
||||
.isIslandsWorld(superiorPlayer.world)
|
||||
) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
return SuperiorSkyblockAPI.getPlayer(player).hasPermission(IslandPrivilege.getByName("Place"))
|
||||
|| SuperiorSkyblockAPI.getPlayer(player).hasPermission(IslandPrivilege.getByName("PLACE"))
|
||||
|
||||
if (!island.hasPermission(superiorPlayer, IslandPrivilege.getByName("BUILD"))) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (!island.isInsideRange(block.location)) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun canInjure(player: Player, victim: LivingEntity): Boolean {
|
||||
if (SuperiorSkyblockAPI.getPlayer(player).hasBypassModeEnabled()) {
|
||||
return true
|
||||
|
||||
val island: Island? = SuperiorSkyblockAPI.getSuperiorSkyblock().grid.getIslandAt(victim.location)
|
||||
|
||||
if (victim is Player) return SuperiorSkyblockAPI.getPlayer(player).canHit(SuperiorSkyblockAPI.getPlayer(victim))
|
||||
.equals(HitActionResult.SUCCESS)
|
||||
|
||||
val islandPermission = when (victim) {
|
||||
is Monster -> IslandPrivilege.getByName("MONSTER_DAMAGE")
|
||||
else -> IslandPrivilege.getByName("ANIMAL_DAMAGE")
|
||||
}
|
||||
return when (victim) {
|
||||
is Player -> SuperiorSkyblockAPI.getPlayer(player).canHit(SuperiorSkyblockAPI.getPlayer(victim)).equals(HitActionResult.SUCCESS)
|
||||
is Animals -> {
|
||||
return SuperiorSkyblockAPI.getPlayer(player).hasPermission(IslandPrivilege.getByName("ANIMAL_DAMAGE"))
|
||||
}
|
||||
is Monster -> {
|
||||
return SuperiorSkyblockAPI.getPlayer(player).hasPermission(IslandPrivilege.getByName("MONSTER_DAMAGE"))
|
||||
}
|
||||
else -> true
|
||||
|
||||
if (island != null && !island.hasPermission(player, islandPermission)) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun canPickupItem(player: Player, location: Location): Boolean {
|
||||
val superiorPlayer: SuperiorPlayer =
|
||||
SuperiorSkyblockAPI.getPlayer(player)
|
||||
val island = SuperiorSkyblockAPI.getSuperiorSkyblock().grid.getIslandAt(location) ?: return true
|
||||
return island.hasPermission(superiorPlayer, IslandPrivilege.getByName("PICKUP_DROPS"))
|
||||
}
|
||||
}
|
||||
@@ -69,6 +69,10 @@ class AntigriefTowny : AntigriefWrapper {
|
||||
return townBlock.permissions.pvp
|
||||
}
|
||||
|
||||
override fun canPickupItem(player: Player, location: Location): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun getPluginName(): String {
|
||||
return "Towny"
|
||||
}
|
||||
|
||||
@@ -98,6 +98,20 @@ class AntigriefWorldGuard : AntigriefWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
override fun canPickupItem(player: Player, location: Location): Boolean {
|
||||
val localPlayer: LocalPlayer = WorldGuardPlugin.inst().wrapPlayer(player)
|
||||
val container: RegionContainer = WorldGuard.getInstance().platform.regionContainer
|
||||
val query: RegionQuery = container.createQuery()
|
||||
val world = location.world
|
||||
Validate.notNull(world, "World cannot be null!")
|
||||
return if (!query.testBuild(BukkitAdapter.adapt(location), localPlayer, Flags.ITEM_PICKUP)) {
|
||||
WorldGuard.getInstance().platform.sessionManager.hasBypass(
|
||||
localPlayer,
|
||||
BukkitAdapter.adapt(world)
|
||||
)
|
||||
} else true
|
||||
}
|
||||
|
||||
override fun getPluginName(): String {
|
||||
return "WorldGuard"
|
||||
}
|
||||
|
||||
@@ -1,21 +1,9 @@
|
||||
package com.willfp.eco.internal.spigot.integrations.bstats
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import org.bstats.bukkit.Metrics
|
||||
import org.bukkit.configuration.file.YamlConfiguration
|
||||
import java.io.File
|
||||
|
||||
object MetricHandler {
|
||||
fun createMetrics(plugin: EcoPlugin, ecoPlugin: EcoPlugin) {
|
||||
val bStatsFolder = File(plugin.dataFolder.parentFile, "bStats")
|
||||
val configFile = File(bStatsFolder, "config.yml")
|
||||
val config = YamlConfiguration.loadConfiguration(configFile)
|
||||
|
||||
if (config.isSet("serverUuid")) {
|
||||
config.set("enabled", ecoPlugin.configYml.getBool("enable-bstats"))
|
||||
config.save(configFile)
|
||||
}
|
||||
|
||||
Metrics(plugin, plugin.bStatsId)
|
||||
fun createMetrics(plugin: EcoPlugin) {
|
||||
Metrics(plugin)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,339 @@
|
||||
package com.willfp.eco.internal.spigot.integrations.bstats
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.configuration.file.YamlConfiguration
|
||||
import java.io.BufferedReader
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.DataOutputStream
|
||||
import java.io.File
|
||||
import java.io.InputStreamReader
|
||||
import java.net.URL
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.util.Arrays
|
||||
import java.util.Objects
|
||||
import java.util.UUID
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.function.BiConsumer
|
||||
import java.util.function.Consumer
|
||||
import java.util.function.Supplier
|
||||
import java.util.logging.Level
|
||||
import java.util.stream.Collectors
|
||||
import java.util.zip.GZIPOutputStream
|
||||
import javax.net.ssl.HttpsURLConnection
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
class Metrics(private val plugin: EcoPlugin) {
|
||||
private val metricsBase: MetricsBase
|
||||
|
||||
private fun appendPlatformData(builder: JsonObjectBuilder) {
|
||||
builder.appendField("playerAmount", playerAmount)
|
||||
builder.appendField("onlineMode", if (Bukkit.getOnlineMode()) 1 else 0)
|
||||
builder.appendField("bukkitVersion", Bukkit.getVersion())
|
||||
builder.appendField("bukkitName", Bukkit.getName())
|
||||
builder.appendField("javaVersion", System.getProperty("java.version"))
|
||||
builder.appendField("osName", System.getProperty("os.name"))
|
||||
builder.appendField("osArch", System.getProperty("os.arch"))
|
||||
builder.appendField("osVersion", System.getProperty("os.version"))
|
||||
builder.appendField("coreCount", Runtime.getRuntime().availableProcessors())
|
||||
}
|
||||
|
||||
private fun appendServiceData(builder: JsonObjectBuilder) {
|
||||
builder.appendField("pluginVersion", plugin.description.version)
|
||||
}
|
||||
|
||||
private val playerAmount: Int
|
||||
get() = Bukkit.getOnlinePlayers().size
|
||||
|
||||
class MetricsBase(
|
||||
private val platform: String,
|
||||
private val serverUuid: String,
|
||||
private val serviceId: Int,
|
||||
private val appendPlatformDataConsumer: Consumer<JsonObjectBuilder>,
|
||||
private val appendServiceDataConsumer: Consumer<JsonObjectBuilder>,
|
||||
private val submitTaskConsumer: Consumer<Runnable>?,
|
||||
private val checkServiceEnabledSupplier: Supplier<Boolean>,
|
||||
private val errorLogger: BiConsumer<String?, Throwable?>,
|
||||
private val infoLogger: Consumer<String>,
|
||||
private val logErrors: Boolean,
|
||||
private val logSentData: Boolean,
|
||||
private val logResponseStatusText: Boolean
|
||||
) {
|
||||
private val customCharts: MutableSet<CustomChart> = HashSet()
|
||||
|
||||
private fun startSubmitting() {
|
||||
val submitTask = Runnable {
|
||||
if (!checkServiceEnabledSupplier.get()) {
|
||||
// Submitting data or service is disabled
|
||||
scheduler.shutdown()
|
||||
return@Runnable
|
||||
}
|
||||
if (submitTaskConsumer != null) {
|
||||
submitTaskConsumer.accept { submitData() }
|
||||
} else {
|
||||
submitData()
|
||||
}
|
||||
}
|
||||
// Many servers tend to restart at a fixed time at xx:00 which causes an uneven distribution
|
||||
// of requests on the
|
||||
// bStats backend. To circumvent this problem, we introduce some randomness into the initial
|
||||
// and second delay.
|
||||
// WARNING: You must not modify and part of this Metrics class, including the submit delay or
|
||||
// frequency!
|
||||
// WARNING: Modifying this code will get your plugin banned on bStats. Just don't do it!
|
||||
val initialDelay = (1000 * 60 * (3 + Math.random() * 3)).toLong()
|
||||
val secondDelay = (1000 * 60 * (Math.random() * 30)).toLong()
|
||||
runIgnoring {
|
||||
scheduler.schedule(submitTask, initialDelay, TimeUnit.MILLISECONDS)
|
||||
scheduler.scheduleAtFixedRate(
|
||||
submitTask, initialDelay + secondDelay, (1000 * 60 * 30).toLong(), TimeUnit.MILLISECONDS
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun submitData() {
|
||||
val baseJsonBuilder = JsonObjectBuilder()
|
||||
appendPlatformDataConsumer.accept(baseJsonBuilder)
|
||||
val serviceJsonBuilder = JsonObjectBuilder()
|
||||
appendServiceDataConsumer.accept(serviceJsonBuilder)
|
||||
val chartData = customCharts.stream()
|
||||
.map { customChart: CustomChart ->
|
||||
customChart.getRequestJsonObject(
|
||||
errorLogger, logErrors
|
||||
)
|
||||
}
|
||||
.filter { obj: JsonObjectBuilder.JsonObject? -> Objects.nonNull(obj) }
|
||||
.toArray()
|
||||
|
||||
serviceJsonBuilder.appendField("id", serviceId)
|
||||
serviceJsonBuilder.appendField(
|
||||
"customCharts",
|
||||
chartData as Array<JsonObjectBuilder.JsonObject>
|
||||
)
|
||||
baseJsonBuilder.appendField("service", serviceJsonBuilder.build())
|
||||
baseJsonBuilder.appendField("serverUUID", serverUuid)
|
||||
baseJsonBuilder.appendField("metricsVersion", METRICS_VERSION)
|
||||
val data = baseJsonBuilder.build()
|
||||
runIgnoring {
|
||||
scheduler.execute {
|
||||
runIgnoring { sendData(data) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
private fun sendData(data: JsonObjectBuilder.JsonObject) {
|
||||
if (logSentData) {
|
||||
infoLogger.accept("Sent bStats metrics data: $data")
|
||||
}
|
||||
val url = String.format(REPORT_URL, platform)
|
||||
val connection = URL(url).openConnection() as HttpsURLConnection
|
||||
// Compress the data to save bandwidth
|
||||
val compressedData = compress(data.toString())
|
||||
connection.requestMethod = "POST"
|
||||
connection.addRequestProperty("Accept", "application/json")
|
||||
connection.addRequestProperty("Connection", "close")
|
||||
connection.addRequestProperty("Content-Encoding", "gzip")
|
||||
connection.addRequestProperty("Content-Length", compressedData!!.size.toString())
|
||||
connection.setRequestProperty("Content-Type", "application/json")
|
||||
connection.setRequestProperty("User-Agent", "Metrics-Service/1")
|
||||
connection.doOutput = true
|
||||
DataOutputStream(connection.outputStream).use { outputStream -> outputStream.write(compressedData) }
|
||||
val builder = StringBuilder()
|
||||
BufferedReader(InputStreamReader(connection.inputStream)).use { bufferedReader ->
|
||||
var line: String?
|
||||
while (bufferedReader.readLine().also { line = it } != null) {
|
||||
builder.append(line)
|
||||
}
|
||||
}
|
||||
if (logResponseStatusText) {
|
||||
infoLogger.accept("Sent data to bStats and received response: $builder")
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val METRICS_VERSION = "2.2.1"
|
||||
private val scheduler =
|
||||
Executors.newScheduledThreadPool(1) { task: Runnable? -> Thread(task, "bStats-Metrics") }
|
||||
private const val REPORT_URL = "https://bStats.org/api/v2/data/%s"
|
||||
|
||||
private fun compress(str: String?): ByteArray? {
|
||||
if (str == null) {
|
||||
return null
|
||||
}
|
||||
val outputStream = ByteArrayOutputStream()
|
||||
GZIPOutputStream(outputStream).use { gzip -> gzip.write(str.toByteArray(StandardCharsets.UTF_8)) }
|
||||
return outputStream.toByteArray()
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
startSubmitting()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
abstract class CustomChart protected constructor(chartId: String?) {
|
||||
private val chartId: String
|
||||
fun getRequestJsonObject(
|
||||
errorLogger: BiConsumer<String?, Throwable?>, logErrors: Boolean
|
||||
): JsonObjectBuilder.JsonObject? {
|
||||
val builder = JsonObjectBuilder()
|
||||
builder.appendField("chartId", chartId)
|
||||
try {
|
||||
val data = chartData
|
||||
?: // If the data is null we don't send the chart.
|
||||
return null
|
||||
builder.appendField("data", data)
|
||||
} catch (t: Throwable) {
|
||||
if (logErrors) {
|
||||
errorLogger.accept("Failed to get data for custom chart with id $chartId", t)
|
||||
}
|
||||
return null
|
||||
}
|
||||
return builder.build()
|
||||
}
|
||||
|
||||
protected abstract val chartData: JsonObjectBuilder.JsonObject?
|
||||
|
||||
init {
|
||||
requireNotNull(chartId) { "chartId must not be null" }
|
||||
this.chartId = chartId
|
||||
}
|
||||
}
|
||||
|
||||
class JsonObjectBuilder {
|
||||
private var builder: StringBuilder? = StringBuilder()
|
||||
private var hasAtLeastOneField = false
|
||||
|
||||
fun appendField(key: String?, value: String?): JsonObjectBuilder {
|
||||
requireNotNull(value) { "JSON value must not be null" }
|
||||
appendFieldUnescaped(key, "\"" + escape(value) + "\"")
|
||||
return this
|
||||
}
|
||||
|
||||
fun appendField(key: String?, value: Int): JsonObjectBuilder {
|
||||
appendFieldUnescaped(key, value.toString())
|
||||
return this
|
||||
}
|
||||
|
||||
fun appendField(key: String?, `object`: JsonObject?): JsonObjectBuilder {
|
||||
requireNotNull(`object`) { "JSON object must not be null" }
|
||||
appendFieldUnescaped(key, `object`.toString())
|
||||
return this
|
||||
}
|
||||
|
||||
fun appendField(key: String?, values: Array<JsonObject>?): JsonObjectBuilder {
|
||||
requireNotNull(values) { "JSON values must not be null" }
|
||||
val escapedValues = Arrays.stream(values).map { obj: JsonObject -> obj.toString() }
|
||||
.collect(Collectors.joining(","))
|
||||
appendFieldUnescaped(key, "[$escapedValues]")
|
||||
return this
|
||||
}
|
||||
|
||||
private fun appendFieldUnescaped(key: String?, escapedValue: String) {
|
||||
checkNotNull(builder) { "JSON has already been built" }
|
||||
requireNotNull(key) { "JSON key must not be null" }
|
||||
if (hasAtLeastOneField) {
|
||||
builder!!.append(",")
|
||||
}
|
||||
builder!!.append("\"").append(escape(key)).append("\":").append(escapedValue)
|
||||
hasAtLeastOneField = true
|
||||
}
|
||||
|
||||
fun build(): JsonObject {
|
||||
checkNotNull(builder) { "JSON has already been built" }
|
||||
val obj = JsonObject(
|
||||
builder!!.append("}").toString()
|
||||
)
|
||||
builder = null
|
||||
return obj
|
||||
}
|
||||
|
||||
class JsonObject(private val value: String) {
|
||||
override fun toString(): String {
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private fun escape(value: String): String {
|
||||
val builder = StringBuilder()
|
||||
for (element in value) {
|
||||
if (element == '"') {
|
||||
builder.append("\\\"")
|
||||
} else if (element == '\\') {
|
||||
builder.append("\\\\")
|
||||
} else if (element <= '\u000F') {
|
||||
builder.append("\\u000").append(Integer.toHexString(element.code))
|
||||
} else if (element <= '\u001F') {
|
||||
builder.append("\\u00").append(Integer.toHexString(element.code))
|
||||
} else {
|
||||
builder.append(element)
|
||||
}
|
||||
}
|
||||
return builder.toString()
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
builder!!.append("{")
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
// Get the config file
|
||||
val bStatsFolder = File(plugin.dataFolder.parentFile, "bStats")
|
||||
val configFile = File(bStatsFolder, "config.yml")
|
||||
val config = YamlConfiguration.loadConfiguration(configFile)
|
||||
if (!config.isSet("serverUuid")) {
|
||||
config.addDefault("enabled", true)
|
||||
config.addDefault("serverUuid", UUID.randomUUID().toString())
|
||||
config.addDefault("logFailedRequests", false)
|
||||
config.addDefault("logSentData", false)
|
||||
config.addDefault("logResponseStatusText", false)
|
||||
// Inform the server owners about bStats
|
||||
config
|
||||
.options()
|
||||
.header(
|
||||
"""
|
||||
bStats (https://bStats.org) collects some basic information for plugin authors, like how
|
||||
many people use their plugin and their total player count. It's recommended to keep bStats
|
||||
enabled, but if you're not comfortable with this, you can turn this setting off. There is no
|
||||
performance penalty associated with having metrics enabled, and data sent to bStats is fully
|
||||
anonymous.
|
||||
""".trimIndent()
|
||||
)
|
||||
.copyDefaults(true)
|
||||
config.save(configFile)
|
||||
}
|
||||
// Load the data
|
||||
val serverUUID = config.getString("serverUuid")!!
|
||||
val logErrors = config.getBoolean("logFailedRequests", false)
|
||||
val logSentData = config.getBoolean("logSentData", false)
|
||||
val logResponseStatusText = config.getBoolean("logResponseStatusText", false)
|
||||
metricsBase = MetricsBase(
|
||||
"bukkit",
|
||||
serverUUID,
|
||||
plugin.bStatsId,
|
||||
{ builder: JsonObjectBuilder -> appendPlatformData(builder) },
|
||||
{ builder: JsonObjectBuilder -> appendServiceData(builder) },
|
||||
{ submitDataTask: Runnable? -> Bukkit.getScheduler().runTask(plugin, submitDataTask!!) },
|
||||
{ plugin.isEnabled },
|
||||
{ message: String?, error: Throwable? -> this.plugin.logger.log(Level.WARNING, message, error) },
|
||||
{ message: String? -> this.plugin.logger.log(Level.INFO, message) },
|
||||
logErrors,
|
||||
logSentData,
|
||||
logResponseStatusText
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun runIgnoring(func: () -> Unit) {
|
||||
try {
|
||||
func()
|
||||
} catch (e: Exception) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.willfp.eco.internal.spigot.integrations.hologram
|
||||
|
||||
import com.willfp.eco.core.integrations.hologram.Hologram
|
||||
import com.willfp.eco.core.integrations.hologram.HologramWrapper
|
||||
import eu.decentsoftware.holograms.api.DHAPI
|
||||
import org.bukkit.Location
|
||||
import java.util.UUID
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
class HologramDecentHolograms : HologramWrapper {
|
||||
override fun createHologram(location: Location, contents: MutableList<String>): Hologram {
|
||||
val id = UUID.randomUUID().toString()
|
||||
|
||||
DHAPI.createHologram(id, location, contents)
|
||||
|
||||
return HologramImplDecentHolograms(id)
|
||||
}
|
||||
|
||||
override fun getPluginName(): String {
|
||||
return "DecentHolograms"
|
||||
}
|
||||
|
||||
class HologramImplDecentHolograms(
|
||||
private val id: String,
|
||||
) : Hologram {
|
||||
override fun remove() {
|
||||
DHAPI.getHologram(id)?.destroy()
|
||||
}
|
||||
|
||||
override fun setContents(contents: MutableList<String>) {
|
||||
DHAPI.setHologramLines(DHAPI.getHologram(id), contents)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ class ShopShopGuiPlus : ShopWrapper {
|
||||
|
||||
override fun loadItem(configurationSection: ConfigurationSection): ItemStack? {
|
||||
val id = configurationSection.getString("eco")
|
||||
return if (id == null) null else Items.lookup(id)?.item
|
||||
return if (id == null) null else Items.lookup(id).item
|
||||
}
|
||||
|
||||
override fun compare(itemStack1: ItemStack, itemStack2: ItemStack): Boolean {
|
||||
|
||||
@@ -9,6 +9,8 @@ mysql:
|
||||
# very high numbers can cause issues with OS configuration. If writes are taking
|
||||
# too long, increase this value.
|
||||
threads: 2
|
||||
# If read operations should be ran in the thread pool. Runs on main thread by default.
|
||||
async-reads: false
|
||||
host: localhost
|
||||
port: 3306
|
||||
database: database
|
||||
@@ -23,10 +25,6 @@ villager-display-fix: false
|
||||
# Disable it if it changes drop mechanics too much for you.
|
||||
use-fast-collated-drops: true
|
||||
|
||||
# bStats is important and you should keep it enabled.
|
||||
# This option is only here because of compliance with data protection laws.
|
||||
enable-bstats: true
|
||||
|
||||
# Some plugins use their own item display systems (eg Triton)
|
||||
# And must be run after eco. Don't enable this unless you run a conflicting plugin
|
||||
# and have been told to enable it.
|
||||
|
||||
@@ -38,15 +38,15 @@ softdepend:
|
||||
- IridiumSkyblock
|
||||
- SuperiorSkyblock2
|
||||
- CrashClaim
|
||||
- DecentHolograms
|
||||
libraries:
|
||||
- 'org.reflections:reflections:0.9.12'
|
||||
- 'org.apache.maven:maven-artifact:3.0.3'
|
||||
- 'org.jetbrains.kotlin:kotlin-stdlib:1.5.31'
|
||||
- 'org.jetbrains.kotlin:kotlin-stdlib:1.6.0'
|
||||
- 'net.kyori:adventure-platform-bukkit:4.0.0'
|
||||
- 'net.kyori:adventure-api:4.9.2'
|
||||
- 'net.kyori:adventure-text-serializer-gson:4.9.2'
|
||||
- 'net.kyori:adventure-text-serializer-legacy:4.9.2'
|
||||
- 'org.jetbrains.kotlin:kotlin-stdlib:1.5.21'
|
||||
- 'net.kyori:adventure-api:4.9.3'
|
||||
- 'net.kyori:adventure-text-serializer-gson:4.9.3'
|
||||
- 'net.kyori:adventure-text-serializer-legacy:4.9.3'
|
||||
- 'org.jetbrains.exposed:exposed-core:0.36.2'
|
||||
- 'org.jetbrains.exposed:exposed-dao:0.36.2'
|
||||
- 'org.jetbrains.exposed:exposed-jdbc:0.36.2'
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
version = 6.13.13
|
||||
plugin-name = eco
|
||||
version = 6.16.0
|
||||
plugin-name = eco
|
||||
kotlin.code.style = official
|
||||
@@ -1,6 +1,6 @@
|
||||
jdk: openjdk16
|
||||
jdk: openjdk17
|
||||
before_install:
|
||||
- source "$HOME/.sdkman/bin/sdkman-init.sh"
|
||||
- sdk update
|
||||
- sdk install java 16.0.1-open
|
||||
- sdk use java 16.0.1-open
|
||||
- sdk install java 17.0.1-tem
|
||||
- sdk use java 17.0.1-tem
|
||||
@@ -13,6 +13,7 @@ include(":eco-core")
|
||||
include(":eco-core:core-nms")
|
||||
include(":eco-core:core-nms:v1_16_R3")
|
||||
include(":eco-core:core-nms:v1_17_R1")
|
||||
include(":eco-core:core-nms:v1_18_R1")
|
||||
include(":eco-core:core-proxy")
|
||||
include(":eco-core:core-plugin")
|
||||
include(":eco-core:core-backend")
|
||||
Reference in New Issue
Block a user