Compare commits

..

122 Commits

Author SHA1 Message Date
Auxilor
b4aeeac570 Added tree growth to PlayerBlockListener.kt 2022-01-05 16:22:52 +00:00
Auxilor
33515aa5f7 Updated to 6.17.7 2022-01-05 13:44:47 +00:00
Auxilor
047b535a40 Merge remote-tracking branch 'origin/master' into develop 2022-01-05 13:44:22 +00:00
Auxilor
ef8093ec7f Updated to 6.17.6 2022-01-05 13:42:24 +00:00
Auxilor
9d0f95617d Fixed CrashClaim integration 2022-01-05 13:42:14 +00:00
Auxilor
183b18c0ec Updated to 6.17.6 2021-12-29 18:47:44 +00:00
Auxilor
e026a767d9 Fixed v1_18_R1 bugs 2021-12-29 18:47:33 +00:00
Auxilor
d2966aa428 Updated to 6.17.5 2021-12-26 17:21:21 +00:00
Auxilor
9168e68b5a StringUtils#jsonToLegacy will now fail silently 2021-12-26 17:21:01 +00:00
Auxilor
51a61b65c6 Updated to 6.17.4 2021-12-26 16:57:54 +00:00
Auxilor
76be236dac Error catching to StringUtils#jsonToLegacy 2021-12-26 16:56:53 +00:00
Auxilor
f1bbac2dd0 Codestyle 2021-12-26 16:48:03 +00:00
Auxilor
6e88aef572 FastItemStack#getLore changes 2021-12-26 16:40:09 +00:00
Auxilor
804f187964 legacy <-> json changes 2021-12-26 16:34:52 +00:00
Auxilor
623b8a18f4 Codestyle 2021-12-26 16:20:38 +00:00
Auxilor
0d4e424582 Codestyle 2021-12-26 16:19:59 +00:00
Auxilor
452e499467 Added NumberUtils#logBase 2021-12-26 16:10:33 +00:00
Auxilor
b2950ab035 Added ListUtils#containsIgnoreCase 2021-12-26 12:53:57 +00:00
Auxilor
e47d05ccb2 NMS changes 2021-12-26 12:23:13 +00:00
Auxilor
b9e61b8c0d Merged v1_18_R1 thanks to paperweight update 2021-12-26 12:17:02 +00:00
Auxilor
0f35d5d16e Updated to 6.17.3 2021-12-21 12:20:33 +00:00
Stealth2800
3a7315d728 Make defensive copy of CustomItem's returned item 2021-12-20 20:24:21 -08:00
Auxilor
6f193f70b0 Staggered player profile loading to load when needed 2021-12-15 12:26:20 +00:00
Auxilor
bab3f078f6 Added @JvmStatic mention to @ConfigUpdater 2021-12-15 11:28:07 +00:00
Auxilor
5b4b17b97f Updated to 6.17.2 2021-12-15 10:31:16 +00:00
Auxilor
f0e02ca25e Added HikariCP to plugin.yml 2021-12-15 10:31:05 +00:00
Auxilor
7426e9adba Updated to use hikari 2021-12-15 10:30:49 +00:00
Auxilor
00905aa9d5 Updated to 6.17.1 2021-12-14 19:09:50 +00:00
Auxilor
f7b57880cb Switched essentials dependency 2021-12-14 19:09:38 +00:00
Auxilor
c1b673e30c Fixed config.yml bug 2021-12-14 08:51:33 +00:00
Auxilor
4cf45795d6 Clarified forRemoval 2021-12-14 08:40:58 +00:00
Auxilor
59d31584e6 Generalized ConfigYml into LoadableConfig for custom implementations 2021-12-14 08:38:51 +00:00
Auxilor
68e1f4afac Added piston moving / retracting support to BlockUtils#isPlayerPlaced 2021-12-14 08:30:34 +00:00
Auxilor
507fad186a Improved PlayerJumpEvent on paper 2021-12-13 13:00:05 +00:00
Auxilor
ca6b3185a3 Fixed legacy configs not having 100% parity 2021-12-13 12:56:22 +00:00
Auxilor
8e96329fdc Fixed ConfigWrapper constructor access 2021-12-13 12:24:12 +00:00
Auxilor
440605f636 Re-made ConfigWrapper abstract 2021-12-13 12:24:01 +00:00
Auxilor
bb686dca17 Config refactor 2021-12-13 12:23:41 +00:00
Auxilor
e595ea2247 Marked AbstractProxy for removal 2021-12-13 12:09:58 +00:00
Auxilor
a776b60f86 Deprecated AbstractProxy 2021-12-13 12:05:49 +00:00
Auxilor
db7ac55eb2 Minor codestyle changes 2021-12-13 11:49:46 +00:00
Auxilor
52d77d7861 Added TestableItem support to ItemStackBuilder 2021-12-13 11:43:36 +00:00
Auxilor
f8ece2d6c7 @NotNull to Handler#getPlayerProfileHandler 2021-12-13 11:35:46 +00:00
Auxilor
b353b5ec04 More javadoc 2021-12-13 10:45:33 +00:00
Auxilor
bbc412e589 Added ListUtils#getOrNull 2021-12-13 10:08:46 +00:00
Auxilor
b4a474c703 Integration / Scheduling changes 2021-12-13 09:59:33 +00:00
Auxilor
75e6a3da79 Documentation and visibility changes 2021-12-13 09:54:39 +00:00
Auxilor
a1afffdbbb Added since to deprecation 2021-12-13 09:35:55 +00:00
Auxilor
f6942192de Added since to deprecation 2021-12-12 15:52:39 +00:00
Auxilor
dab26cbe95 Deprecation changes and warnings 2021-12-12 15:47:46 +00:00
Auxilor
b945a3f948 Improved deprecation javadoc 2021-12-12 15:43:25 +00:00
Auxilor
b2c1d650de Removed DeprecatedIsStillUsed suppressions 2021-12-12 14:21:23 +00:00
Auxilor
4b994d5f4c Fixed javadoc 2021-12-12 14:04:53 +00:00
Auxilor
ed2dffb52c Fixed internal use of YamlBaseConfig 2021-12-12 14:04:21 +00:00
Auxilor
20c870da06 Fixed internal use of deprecated config class 2021-12-12 14:01:28 +00:00
Auxilor
7684e431f5 Even more config parity fixes 2021-12-12 13:58:53 +00:00
Auxilor
abcc13685f Fixed config parity bugs 2021-12-12 13:55:15 +00:00
Auxilor
ac902eaa08 Overhauled config system 2021-12-12 13:44:58 +00:00
Auxilor
4e52913504 Javadoc 2021-12-12 12:47:37 +00:00
Auxilor
7505f7732f Merge remote-tracking branch 'origin/dependabot/gradle/com.github.johnrengelman.shadow-7.1.0' into develop 2021-12-12 12:43:40 +00:00
Auxilor
15fae21fd5 Merge remote-tracking branch 'origin/dependabot/gradle/com.massivecraft-Factions-1.6.9.5-2.7.0-STABLE' into develop 2021-12-12 12:43:36 +00:00
Auxilor
e9d98816ce Merge remote-tracking branch 'origin/dependabot/gradle/org.junit.jupiter-junit-jupiter-api-5.8.2' into develop
# Conflicts:
#	build.gradle.kts
2021-12-12 12:43:32 +00:00
Auxilor
675fc07ebf Merge remote-tracking branch 'origin/dependabot/gradle/org.junit.jupiter-junit-jupiter-engine-5.8.2' into develop 2021-12-12 12:43:11 +00:00
Auxilor
b8b8fd70b5 Javadoc 2021-12-12 12:42:16 +00:00
Auxilor
1d9fca1fb8 Added permissions to recipes 2021-12-12 12:38:04 +00:00
Auxilor
9b83f6eab4 Added ListUtils#toSingletonList 2021-12-12 12:17:45 +00:00
Auxilor
8190660b8f Removed redundant suppression 2021-12-12 12:14:50 +00:00
Auxilor
cbf4d111fb More dev niceties 2021-12-12 12:14:24 +00:00
Auxilor
6a139bef67 Kotlin-friendliness 2021-12-12 12:09:12 +00:00
Auxilor
9e3fecfd13 Updated to 6.17.0 2021-12-12 12:00:20 +00:00
Auxilor
3b260e2e5d Improved command system 2021-12-12 12:00:09 +00:00
Auxilor
0c0370e256 Updated to 6.16.2 2021-12-08 20:47:22 +00:00
Auxilor
227b748f85 Fixed bStats issues 2021-12-08 20:46:26 +00:00
Auxilor
c8382bd8cf Updated to 6.16.1 2021-12-08 20:40:59 +00:00
Auxilor
df22768367 Fixed bugs 2021-12-08 20:40:39 +00:00
Auxilor
00ea3506ca config.yml changes 2021-12-08 20:32:55 +00:00
Auxilor
521659cfec bStats changes 2021-12-08 20:32:31 +00:00
Auxilor
bbe5f1eba4 Merge remote-tracking branch 'origin/develop' into develop
# Conflicts:
#	eco-core/core-plugin/build.gradle
2021-12-08 20:24:07 +00:00
dependabot[bot]
3d4c33860a Bump junit-jupiter-engine from 5.8.1 to 5.8.2
Bumps [junit-jupiter-engine](https://github.com/junit-team/junit5) from 5.8.1 to 5.8.2.
- [Release notes](https://github.com/junit-team/junit5/releases)
- [Commits](https://github.com/junit-team/junit5/compare/r5.8.1...r5.8.2)

---
updated-dependencies:
- dependency-name: org.junit.jupiter:junit-jupiter-engine
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-08 20:18:37 +00:00
Auxilor
eae5d29f8d Downgraded bStats 2021-12-08 20:16:59 +00:00
Auxilor
c878d6fd12 Implemented stipped-down bStats directly (recoded in kotlin) 2021-12-08 16:08:03 +00:00
Auxilor
2b97c0072f Downgraded bStats 2021-12-08 14:18:24 +00:00
Auxilor
63079df745 Removed explicit buffer size 2021-12-08 12:41:24 +00:00
Auxilor
079b41e877 Switched to old config behavior 2021-12-08 12:40:13 +00:00
Auxilor
1aaab459d8 Updated bStats to 2.2.1 2021-12-08 12:34:38 +00:00
Auxilor
db78c2eb4c Fixed javadoc + codestyle 2021-12-08 12:22:51 +00:00
Auxilor
02fd07b3c8 Fixed shadowed name 2021-12-08 12:17:22 +00:00
Auxilor
3de2e53031 Fixed default captive items bug 2021-12-08 11:27:33 +00:00
Auxilor
cb088bb70b Allowed specifiying default captive items 2021-12-08 11:23:23 +00:00
Auxilor
36fca7016f Fixed ArgParserEnchantment never returning null 2021-12-08 11:11:59 +00:00
Auxilor
7e1137da06 Cleaned up SS2 integration 2021-12-08 10:53:16 +00:00
Auxilor
0da104d614 Added color:#fffff support x 2021-12-08 10:51:25 +00:00
Auxilor
9095de7d19 Updated to 6.16.0 2021-12-08 10:50:36 +00:00
Auxilor
7a8abac1a2 Pull Request Fixes / Changes, config changes 2021-12-08 10:50:12 +00:00
0ft3n
1ddcb6e964 Merge branch 'master' into master 2021-12-07 14:11:40 +03:00
_OfTeN_
4d0858ad84 Added AntigriefManager#canPickupItem and created and implemented DropQueuePushEvent event 2021-12-07 14:08:04 +03:00
_OfTeN_
3d05695a36 Added Items#getItem 2021-12-07 13:30:36 +03:00
Auxilor
d676be15ce Grammar 2021-12-06 13:46:27 +00:00
Auxilor
16848caec1 Fixed grammar errors 2021-12-06 13:08:45 +00:00
Auxilor
ef26fe4629 Removed legacy arg parser method bodies 2021-12-06 13:06:22 +00:00
Auxilor
29fbd785d7 Added ArgParserName 2021-12-06 12:54:28 +00:00
Auxilor
8c73676ee0 Added ArgParserUnbreakable 2021-12-06 12:50:26 +00:00
Auxilor
ebf27d28d9 Updated to 6.15.2 2021-12-06 12:49:10 +00:00
Auxilor
317bc13f65 Moved arg parsers to internals and added ArgParserFlag 2021-12-06 12:49:00 +00:00
Auxilor
b8ec0ee6fc Updated to 6.15.1 2021-12-06 10:14:14 +00:00
Auxilor
307e57c902 Display frame changes with PacketHeldWindowItems 2021-12-06 10:13:29 +00:00
Auxilor
db0d55659f Empty transient config 2021-12-06 10:10:35 +00:00
Auxilor
548529feb3 Javadoc formatting 2021-12-06 10:09:52 +00:00
Auxilor
fb56baf452 Fixed class-cast error 2021-12-06 10:02:24 +00:00
Auxilor
5d18b424d7 Added ColorArgParser 2021-12-04 15:37:29 +00:00
Auxilor
7be9a1bd10 Fixed EcoYamlConfigWrapper cast issues 2021-12-03 20:59:07 +00:00
Auxilor
97c39b56dd Updated to 6.15.0 2021-12-03 20:23:25 +00:00
_OfTeN_
3a9f5bc139 Added support for DecentHolograms 2021-12-03 21:10:40 +03:00
Auxilor
1e5955f249 Codestyle fixes 2021-12-03 16:21:47 +00:00
Auxilor
bad076bbe9 Added kotlin.code.style = official 2021-12-03 16:18:53 +00:00
Auxilor
e219b2f33c Config additions 2021-12-03 16:13:37 +00:00
Auxilor
2f7603409e Generic variance 2021-12-03 15:58:41 +00:00
Auxilor
28cdb65176 Added Config#getSubsections 2021-12-03 15:49:00 +00:00
_OfTeN_
03ae9e89b3 Added color:#FFFFFF, color:FFFFFF or color:red,green,blue parser for leather armor color 2021-12-02 23:26:38 +03:00
dependabot[bot]
651426ed76 Bump junit-jupiter-api from 5.8.1 to 5.8.2
Bumps [junit-jupiter-api](https://github.com/junit-team/junit5) from 5.8.1 to 5.8.2.
- [Release notes](https://github.com/junit-team/junit5/releases)
- [Commits](https://github.com/junit-team/junit5/compare/r5.8.1...r5.8.2)

---
updated-dependencies:
- dependency-name: org.junit.jupiter:junit-jupiter-api
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-30 19:41:43 +00:00
dependabot[bot]
1a49165656 Bump com.github.johnrengelman.shadow from 7.0.0 to 7.1.0
Bumps com.github.johnrengelman.shadow from 7.0.0 to 7.1.0.

---
updated-dependencies:
- dependency-name: com.github.johnrengelman.shadow
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-26 19:13:10 +00:00
dependabot[bot]
a48c3c2fed Bump Factions from 1.6.9.5-U0.5.10 to 1.6.9.5-2.7.0-STABLE
Bumps Factions from 1.6.9.5-U0.5.10 to 1.6.9.5-2.7.0-STABLE.

---
updated-dependencies:
- dependency-name: com.massivecraft:Factions
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-15 21:04:02 +00:00
148 changed files with 2842 additions and 686 deletions

View File

@@ -1,6 +1,6 @@
plugins {
id("java-library")
id("com.github.johnrengelman.shadow") version "7.0.0"
id("com.github.johnrengelman.shadow") version "7.1.0"
id("maven-publish")
id("java")
}
@@ -12,7 +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"))
implementation(project(path = ":eco-core:core-nms:v1_18_R1", configuration = "reobf"))
}
allprojects {
@@ -35,7 +35,7 @@ allprojects {
// 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
@@ -68,7 +68,7 @@ allprojects {
// Test
testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.1")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.2")
// Adventure
compileOnly("net.kyori:adventure-api:4.9.3")

View File

@@ -5,10 +5,13 @@ import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
/**
* Base class to hold the handler.
* Holds the instance of the eco handler for bridging between the frontend
* and backend.
*
* @see Eco#getHandler()
* @see Handler
*/
@ApiStatus.Internal
public final class Eco {
/**
* Instance of eco handler.
@@ -18,6 +21,7 @@ public final class Eco {
/**
* Set the handler.
*
* @param handler The handler.
*/
@ApiStatus.Internal
@@ -28,18 +32,18 @@ public final class Eco {
}
/**
* Get the instance of the eco handler.
* Get the instance of the eco handler; the bridge between the api frontend
* and the implementation backend.
* <p>
* The handler is, in essence, a way to interface between the eco-api
* frontend module, and the eco-backend implementations.
* <strong>Do not use the handler in your plugins!</strong> It can and will contain
* breaking changes between minor versions and even patches, and you will create
* compatibility issues by using the handler. All parts of the handler have been abstracted
* into logically named API components that you can use.
* <p>
* There shouldn't really be any reason to ever use the handler
* in your own plugins, and you are likely to break things. All parts of
* the handler are abstracted into logically named parts of the API.
* <p>
* In versions of eco before 6.12.0, the handler was considered part of
* the eco API, however it has since been moved into an internal component
* that shouldn't be used in your plugins.
* Prior to version 6.12.0, the handler was considered as an API component, but it has
* since been moved into an internal component, and in 6.17.0, the first breaking change
* was introduced to {@link com.willfp.eco.core.config.wrapper.ConfigFactory}. This means
* that any usages of the handler can now cause problems in your plugins.
*
* @return The handler.
*/

View File

@@ -14,7 +14,6 @@ import com.willfp.eco.core.factory.NamespacedKeyFactory;
import com.willfp.eco.core.factory.RunnableFactory;
import com.willfp.eco.core.integrations.IntegrationLoader;
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager;
import com.willfp.eco.core.proxy.AbstractProxy;
import com.willfp.eco.core.proxy.ProxyFactory;
import com.willfp.eco.core.scheduling.Scheduler;
import com.willfp.eco.core.web.UpdateChecker;
@@ -32,6 +31,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.logging.Logger;
import java.util.stream.Collectors;
@@ -636,7 +636,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param <T> The proxy type.
* @return The proxy.
*/
public final <T extends AbstractProxy> T getProxy(@NotNull final Class<T> proxyClass) {
public final <T> T getProxy(@NotNull final Class<T> proxyClass) {
Validate.notNull(proxyFactory, "Plugin does not support proxy!");
return proxyFactory.getProxy(proxyClass);
@@ -655,7 +655,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
public final FileConfiguration getConfig() {
this.getLogger().warning("Call to default config method in eco plugin!");
return this.getConfigYml().getBukkitHandle();
return Objects.requireNonNull(this.getConfigYml().getBukkitHandle());
}
/**

View File

@@ -230,5 +230,6 @@ public interface Handler {
*
* @return The handler.
*/
@NotNull
PlayerProfileHandler getPlayerProfileHandler();
}

View File

@@ -4,6 +4,13 @@ import org.jetbrains.annotations.NotNull;
/**
* Quick DI class to manage passing eco plugins.
* <p>
* Basically just a quick bit of laziness if you can't be bothered to add a private field
* and a protected getter, don't use this in kotlin as you can just specify
* {@code
* private val plugin: EcoPlugin
* }
* in the constructor.
*
* @param <T> The eco plugin type.
*/

View File

@@ -3,6 +3,7 @@ package com.willfp.eco.core;
import com.willfp.eco.core.config.updating.ConfigHandler;
import java.io.File;
import java.util.logging.Logger;
/**
* Represents any class that acts like a plugin, for example {@link EcoPlugin}
@@ -26,4 +27,11 @@ public interface PluginLike {
* @return The config handler.
*/
ConfigHandler getConfigHandler();
/**
* Get the logger.
*
* @return The logger.
*/
Logger getLogger();
}

View File

@@ -1,7 +1,11 @@
package com.willfp.eco.core.command;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
* Interface for all command implementations.
*/
@@ -35,31 +39,70 @@ public interface CommandBase {
*/
CommandBase addSubcommand(@NotNull CommandBase command);
/**
* Handle command execution.
* <p>
* Marked as default void with no implementation for backwards compatibility.
*
* @param sender The sender.
* @param args The args.
*/
default void onExecute(@NotNull CommandSender sender,
@NotNull List<String> args) {
// Do nothing.
}
/**
* Handle tab completion.
* <p>
* Marked as default void with no implementation for backwards compatibility.
*
* @param sender The sender.
* @param args The args.
* @return The results.
*/
default List<String> tabComplete(@NotNull CommandSender sender,
@NotNull List<String> args) {
return new ArrayList<>();
}
/**
* Get the handler.
*
* @return The handler.
* @see CommandHandler
* @deprecated Use {@link CommandBase#onExecute(CommandSender, List)} instead.
*/
@Deprecated
CommandHandler getHandler();
/**
* Set the handler.
*
* @param handler The handler.
* @see CommandHandler
* @deprecated Handlers have been deprecated.
*/
@Deprecated
void setHandler(@NotNull CommandHandler handler);
/**
* Get the tab completer.
*
* @return The tab completer.
* @see TabCompleteHandler
* @deprecated Use {@link CommandBase#tabComplete(CommandSender, List)} instead.
*/
@Deprecated
TabCompleteHandler getTabCompleter();
/**
* Set the tab completer.
*
* @param handler The handler.
* @see TabCompleteHandler
* @deprecated Handlers have been deprecated.
*/
@Deprecated
void setTabCompleter(@NotNull TabCompleteHandler handler);
}

View File

@@ -10,9 +10,13 @@ import java.util.List;
* A command handler handles the actual code for a command.
* <p>
* The replacement for {@link org.bukkit.command.CommandExecutor#onCommand(CommandSender, Command, String, String[])}
*
* @see CommandBase
* @deprecated Handlers have been deprecated. This legacy system will eventually be removed,
* update to use the new system: {@link CommandBase#onExecute(CommandSender, List)}.
*/
@FunctionalInterface
@Deprecated(since = "6.17.0")
public interface CommandHandler {
/**
* The code to be called on execution.

View File

@@ -10,9 +10,13 @@ import java.util.List;
* A Tab Complete handler handles the actual tab-completion code.
* <p>
* The replacement for {@link org.bukkit.command.TabCompleter#onTabComplete(CommandSender, Command, String, String[])}
*
* @see CommandBase
* @deprecated Handlers have been deprecated. This legacy system will eventually be removed,
* update to use the new system: {@link CommandBase#tabComplete(CommandSender, List)}
*/
@FunctionalInterface
@Deprecated(since = "6.17.0")
public interface TabCompleteHandler {
/**
* Handle Tab Completion.

View File

@@ -9,6 +9,7 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
@@ -23,6 +24,7 @@ import java.util.stream.Collectors;
* in order to execute the command-specific code. It's essentially an internal
* layer, hence why it's a package-private class.
*/
@SuppressWarnings({"DeprecatedIsStillUsed"})
abstract class HandledCommand extends PluginDependent<EcoPlugin> implements CommandBase {
/**
* The name of the command.
@@ -46,14 +48,16 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
/**
* The actual code to be executed in the command.
*/
private CommandHandler handler = (sender, args) -> {
// Do nothing by default
};
@Deprecated
@Nullable
private CommandHandler handler = null;
/**
* The tab completion code to be executed in the command.
*/
private TabCompleteHandler tabCompleter = (sender, args) -> new ArrayList<>();
@Deprecated
@Nullable
private TabCompleteHandler tabCompleter = null;
/**
* All subcommands for the command.
@@ -120,7 +124,11 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
}
}
this.getHandler().onExecute(sender, Arrays.asList(args));
if (this.getHandler() != null) {
this.getHandler().onExecute(sender, Arrays.asList(args));
} else {
this.onExecute(sender, Arrays.asList(args));
}
}
/**
@@ -167,7 +175,11 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
}
}
return this.getTabCompleter().tabComplete(sender, Arrays.asList(args));
if (this.getTabCompleter() != null) {
return this.getTabCompleter().tabComplete(sender, Arrays.asList(args));
} else {
return this.tabComplete(sender, Arrays.asList(args));
}
}
/**
@@ -221,24 +233,6 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
return this.playersOnly;
}
/**
* Get the actual code to be executed in the command.
*
* @return The code.
*/
public CommandHandler getHandler() {
return this.handler;
}
/**
* Get the tab completion code to be executed in the command.
*
* @return The code.
*/
public TabCompleteHandler getTabCompleter() {
return this.tabCompleter;
}
/**
* Get the subcommands of the command.
*
@@ -248,21 +242,27 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
return this.subcommands;
}
/**
* Set the command handler.
*
* @param handler The handler.
*/
public void setHandler(@NotNull final CommandHandler handler) {
@Deprecated
@Override
public @Nullable CommandHandler getHandler() {
return this.handler;
}
@Deprecated
@Override
public @Nullable TabCompleteHandler getTabCompleter() {
return this.tabCompleter;
}
@Deprecated
@Override
public void setHandler(@Nullable final CommandHandler handler) {
this.handler = handler;
}
/**
* Set the tab completer.
*
* @param tabCompleter The tab completer.
*/
public void setTabCompleter(@NotNull final TabCompleteHandler tabCompleter) {
@Deprecated
@Override
public void setTabCompleter(@Nullable final TabCompleteHandler tabCompleter) {
this.tabCompleter = tabCompleter;
}
}

View File

@@ -12,7 +12,9 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* PluginCommands are the class to be used instead of CommandExecutor.
* PluginCommands are the class to be used instead of CommandExecutor,
* they function as the base command, e.g. {@code /ecoenchants} would be a base command, with each
* subsequent argument functioning as subcommands.
* <p>
* The command will not be registered until register() is called.
* <p>

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.core.config;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.wrapper.LoadableConfigWrapper;
import org.jetbrains.annotations.NotNull;
/**
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
* <p>
* Automatically updates.
*/
public abstract class BaseConfig extends LoadableConfigWrapper {
/**
* Create new Base Config.
*
* @param plugin The plugin or extension.
* @param configName The config name (excluding extension).
* @param removeUnused If unused sections should be removed.
* @param type The config type.
*/
protected BaseConfig(@NotNull final String configName,
@NotNull final PluginLike plugin,
final boolean removeUnused,
@NotNull final ConfigType type) {
super(Eco.getHandler().getConfigFactory().createUpdatableConfig(
configName,
plugin,
"",
plugin.getClass(),
removeUnused,
type
));
}
}

View File

@@ -0,0 +1,16 @@
package com.willfp.eco.core.config;
/**
* Config types, classified by file extension.
*/
public enum ConfigType {
/**
* .json config.
*/
JSON,
/**
* .yml config.
*/
YAML
}

View File

@@ -0,0 +1,44 @@
package com.willfp.eco.core.config;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.wrapper.LoadableConfigWrapper;
import org.jetbrains.annotations.NotNull;
/**
* Config implementation for configs present in one of two places:
* <ul>
* <li>Plugin base directory (eg config.yml, lang.json)</li>
* <li>Other extension's configs</li>
* </ul>
* <p>
* Automatically updates.
*/
public abstract class ExtendableConfig extends LoadableConfigWrapper {
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
* @param subDirectoryPath The subdirectory path.
* @param type The config type.
* @param source The class that owns the resource.
*/
protected ExtendableConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final PluginLike plugin,
@NotNull final Class<?> source,
@NotNull final String subDirectoryPath,
@NotNull final ConfigType type,
@NotNull final String... updateBlacklist) {
super(Eco.getHandler().getConfigFactory().createUpdatableConfig(
configName,
plugin,
subDirectoryPath,
source,
removeUnused,
type,
updateBlacklist
));
}
}

View File

@@ -0,0 +1,32 @@
package com.willfp.eco.core.config;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.wrapper.LoadableConfigWrapper;
import org.jetbrains.annotations.NotNull;
/**
* Non-updatable yaml config that exists within a plugin jar.
*/
public abstract class StaticBaseConfig extends LoadableConfigWrapper {
/**
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
* <p>
* Does not automatically update.
*
* @param configName The name of the config
* @param plugin The plugin.
* @param type The config type.
*/
protected StaticBaseConfig(@NotNull final String configName,
@NotNull final PluginLike plugin,
@NotNull final ConfigType type) {
super(Eco.getHandler().getConfigFactory().createLoadableConfig(
configName,
plugin,
"",
plugin.getClass(),
type
));
}
}

View File

@@ -0,0 +1,48 @@
package com.willfp.eco.core.config;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.config.wrapper.ConfigWrapper;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
/**
* Config that exists purely in the code, not linked to any file.
* <p>
* Use for inline configs to move data around or to add subsections to other configs.
*/
public class TransientConfig extends ConfigWrapper<Config> {
/**
* @param config The YamlConfiguration handle.
*/
public TransientConfig(@NotNull final YamlConfiguration config) {
super(Eco.getHandler().getConfigFactory().createConfig(config));
}
/**
* Create a new empty transient config.
*
* @param values The values.
*/
public TransientConfig(@NotNull final Map<String, Object> values) {
super(Eco.getHandler().getConfigFactory().createConfig(values));
}
/**
* Create a new empty transient config.
*/
public TransientConfig() {
super(Eco.getHandler().getConfigFactory().createConfig("", ConfigType.YAML));
}
/**
* @param contents The contents of the config.
* @param type The config type.
*/
public TransientConfig(@NotNull final String contents,
@NotNull final ConfigType type) {
super(Eco.getHandler().getConfigFactory().createConfig(contents, type));
}
}

View File

@@ -1,20 +1,21 @@
package com.willfp.eco.core.config.base;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.config.yaml.YamlBaseConfig;
import com.willfp.eco.core.config.BaseConfig;
import com.willfp.eco.core.config.ConfigType;
import org.jetbrains.annotations.NotNull;
/**
* Default plugin config.yml.
*/
public class ConfigYml extends YamlBaseConfig {
public class ConfigYml extends BaseConfig {
/**
* Config.yml.
*
* @param plugin The plugin.
*/
public ConfigYml(@NotNull final EcoPlugin plugin) {
super("config", true, plugin);
super("config", plugin, true, ConfigType.YAML);
}
/**
@@ -25,7 +26,7 @@ public class ConfigYml extends YamlBaseConfig {
*/
public ConfigYml(@NotNull final EcoPlugin plugin,
final boolean removeUnused) {
super("config", removeUnused, plugin);
super("config", plugin, removeUnused, ConfigType.YAML);
}
/**
@@ -36,7 +37,7 @@ public class ConfigYml extends YamlBaseConfig {
*/
public ConfigYml(@NotNull final EcoPlugin plugin,
@NotNull final String name) {
super(name, true, plugin);
super(name, plugin, true, ConfigType.YAML);
}
/**
@@ -49,7 +50,6 @@ public class ConfigYml extends YamlBaseConfig {
public ConfigYml(@NotNull final EcoPlugin plugin,
@NotNull final String name,
final boolean removeUnused) {
super(name, removeUnused, plugin);
super(name, plugin, removeUnused, ConfigType.YAML);
}
}

View File

@@ -1,21 +1,22 @@
package com.willfp.eco.core.config.base;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.config.yaml.YamlBaseConfig;
import com.willfp.eco.core.config.BaseConfig;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.util.StringUtils;
import org.jetbrains.annotations.NotNull;
/**
* Default plugin lang.yml.
*/
public class LangYml extends YamlBaseConfig {
public class LangYml extends BaseConfig {
/**
* Lang.yml.
*
* @param plugin The plugin.
*/
public LangYml(@NotNull final EcoPlugin plugin) {
super("lang", false, plugin);
super("lang", plugin, false, ConfigType.YAML);
}
/**

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core.config.interfaces;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.util.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -7,7 +8,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* All canfigs implement this interface.
* All configs implement this interface.
* <p>
* Contains all methods that must exist in yaml and json configurations.
*/
@@ -524,6 +525,32 @@ 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);
/**
* Get config type.
*
* @return The type.
*/
@NotNull
ConfigType getType();
/**
* Clone the config.
*

View File

@@ -6,10 +6,14 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* JSON configs have extra methods compared to yaml configs.
* <p>
* If you need to use them, then use JSONConfig instead.
* JSON config.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
@SuppressWarnings("DeprecatedIsStillUsed")
public interface JSONConfig extends Config {
/**
* Get a list of subsections from config.

View File

@@ -1,12 +1,16 @@
package com.willfp.eco.core.config.interfaces;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
/**
* Interface for configs that physically exist as files in plugins.
*/
public interface LoadableConfig {
public interface LoadableConfig extends Config {
/**
* Create the file.
*/
@@ -39,4 +43,18 @@ public interface LoadableConfig {
* @return The name.
*/
String getName();
/**
* Get bukkit {@link YamlConfiguration}.
* <p>
* This method is not recommended unless absolutely required as it
* only returns true if the type of config is {@link com.willfp.eco.core.config.ConfigType#YAML},
* and if the handle is an {@link YamlConfiguration} specifically. This depends on the internals
* and the implementation, and so may cause problems - it exists mostly for parity with
* {@link JavaPlugin#getConfig()}.
*
* @return The config, or null if config is not yaml-based.
*/
@Nullable
YamlConfiguration getBukkitHandle();
}

View File

@@ -5,8 +5,12 @@ import org.bukkit.configuration.file.YamlConfiguration;
/**
* Interface for configs that wrap an {@link YamlConfiguration}.
*
* @see com.willfp.eco.core.config.yaml.wrapper.YamlConfigWrapper
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
@SuppressWarnings("DeprecatedIsStillUsed")
public interface WrappedYamlConfiguration {
/**
* Get the ConfigurationSection handle.

View File

@@ -3,6 +3,8 @@ package com.willfp.eco.core.config.json;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
import org.jetbrains.annotations.NotNull;
@@ -10,7 +12,12 @@ import org.jetbrains.annotations.NotNull;
* Config implementation for configs present in the plugin's base directory (eg config.json).
* <p>
* Automatically updates.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class JSONBaseConfig extends LoadableJSONConfigWrapper {
/**
* @param configName The name of the config
@@ -23,13 +30,16 @@ public abstract class JSONBaseConfig extends LoadableJSONConfigWrapper {
@NotNull final PluginLike plugin,
@NotNull final String... updateBlacklist) {
super(
Eco.getHandler().getConfigFactory().createUpdatableJSONConfig(
configName,
plugin,
"",
plugin.getClass(),
removeUnused, updateBlacklist
)
(JSONConfig)
Eco.getHandler().getConfigFactory().createUpdatableConfig(
configName,
plugin,
"",
plugin.getClass(),
removeUnused,
ConfigType.JSON,
updateBlacklist
)
);
}
@@ -42,13 +52,15 @@ public abstract class JSONBaseConfig extends LoadableJSONConfigWrapper {
final boolean removeUnused,
@NotNull final PluginLike plugin) {
super(
Eco.getHandler().getConfigFactory().createUpdatableJSONConfig(
configName,
plugin,
"",
plugin.getClass(),
removeUnused
)
(JSONConfig)
Eco.getHandler().getConfigFactory().createUpdatableConfig(
configName,
plugin,
"",
plugin.getClass(),
removeUnused,
ConfigType.JSON
)
);
}

View File

@@ -3,6 +3,8 @@ package com.willfp.eco.core.config.json;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
import org.jetbrains.annotations.NotNull;
@@ -14,7 +16,12 @@ import org.jetbrains.annotations.NotNull;
* </ul>
* <p>
* Automatically updates.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class JSONExtendableConfig extends LoadableJSONConfigWrapper {
/**
* @param configName The name of the config
@@ -31,16 +38,19 @@ public abstract class JSONExtendableConfig extends LoadableJSONConfigWrapper {
@NotNull final String subDirectoryPath,
@NotNull final String... updateBlacklist) {
super(
Eco.getHandler().getConfigFactory().createUpdatableJSONConfig(
configName,
plugin,
subDirectoryPath,
source,
removeUnused,
updateBlacklist
)
(JSONConfig)
Eco.getHandler().getConfigFactory().createUpdatableConfig(
configName,
plugin,
subDirectoryPath,
source,
removeUnused,
ConfigType.JSON,
updateBlacklist
)
);
}
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.

View File

@@ -3,12 +3,19 @@ package com.willfp.eco.core.config.json;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
import org.jetbrains.annotations.NotNull;
/**
* Non-updatable JSON config that exists within a plugin jar.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class JSONStaticBaseConfig extends LoadableJSONConfigWrapper {
/**
* Config implementation for configs present in the plugin's base directory (eg config.json, lang.json).
@@ -20,7 +27,7 @@ public abstract class JSONStaticBaseConfig extends LoadableJSONConfigWrapper {
*/
protected JSONStaticBaseConfig(@NotNull final String configName,
@NotNull final PluginLike plugin) {
super(Eco.getHandler().getConfigFactory().createLoadableJSONConfig(configName, plugin, "", plugin.getClass()));
super((JSONConfig) Eco.getHandler().getConfigFactory().createLoadableConfig(configName, plugin, "", plugin.getClass(), ConfigType.JSON));
}
/**

View File

@@ -1,14 +1,21 @@
package com.willfp.eco.core.config.json;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.eco.core.config.json.wrapper.JSONConfigWrapper;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
/**
* Raw JSON config with a map of values at its core.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public class JSONTransientConfig extends JSONConfigWrapper {
/**
* Config implementation for passing maps.
@@ -18,6 +25,13 @@ public class JSONTransientConfig extends JSONConfigWrapper {
* @param values The map of values.
*/
public JSONTransientConfig(@NotNull final Map<String, Object> values) {
super(Eco.getHandler().getConfigFactory().createJSONConfig(values));
super((JSONConfig) Eco.getHandler().getConfigFactory().createConfig(values));
}
/**
* Empty JSON config.
*/
public JSONTransientConfig() {
super((JSONConfig) Eco.getHandler().getConfigFactory().createConfig(new HashMap<>()));
}
}

View File

@@ -9,7 +9,12 @@ import java.util.List;
/**
* Wrapper to handle the backend JSON config implementations.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class JSONConfigWrapper extends ConfigWrapper<JSONConfig> implements JSONConfig {
/**
* Create a config wrapper.

View File

@@ -3,14 +3,21 @@ package com.willfp.eco.core.config.json.wrapper;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.eco.core.config.interfaces.LoadableConfig;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
/**
* Wrapper to handle the backend loadable JSON config implementations.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class LoadableJSONConfigWrapper extends JSONConfigWrapper implements LoadableConfig {
/**
* Create a config wrapper.
@@ -48,4 +55,9 @@ public abstract class LoadableJSONConfigWrapper extends JSONConfigWrapper implem
public String getName() {
return ((LoadableConfig) this.getHandle()).getName();
}
@Override
public @Nullable YamlConfiguration getBukkitHandle() {
return null;
}
}

View File

@@ -23,10 +23,14 @@ import java.lang.annotation.Target;
* <p>
* The second:
* <pre>{@code
* public static void update(EcoPlugin plugin) {}
* public static void update(EcoPlugin plugin) {
* // Update code
* }
* }</pre>
* <p>
* If using kotlin, you have to annotate the method with {@code @JvmStatic}
* in order to prevent null pointer exceptions.
* <p>
* Config update methods in all classes in a plugin jar will be called
* on reload.
* <p>

View File

@@ -1,9 +1,11 @@
package com.willfp.eco.core.config.wrapper;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.eco.core.config.interfaces.LoadableConfig;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
@@ -11,6 +13,7 @@ import java.util.Map;
/**
* Internal component to create backend config implementations.
*/
@ApiStatus.Internal
public interface ConfigFactory {
/**
* Updatable config.
@@ -20,75 +23,57 @@ public interface ConfigFactory {
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param type The config type.
* @param updateBlacklist Substring of keys to not add/remove keys for.
* @return The config implementation.
*/
Config createUpdatableYamlConfig(@NotNull String configName,
@NotNull PluginLike plugin,
@NotNull String subDirectoryPath,
@NotNull Class<?> source,
boolean removeUnused,
@NotNull String... updateBlacklist);
/**
* Updatable config.
*
* @param configName The name of the config
* @param plugin The plugin.
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param updateBlacklist Substring of keys to not add/remove keys for.
* @return The config implementation.
*/
JSONConfig createUpdatableJSONConfig(@NotNull String configName,
LoadableConfig createUpdatableConfig(@NotNull String configName,
@NotNull PluginLike plugin,
@NotNull String subDirectoryPath,
@NotNull Class<?> source,
boolean removeUnused,
@NotNull ConfigType type,
@NotNull String... updateBlacklist);
/**
* JSON loadable config.
* Loadable config.
*
* @param configName The name of the config
* @param plugin The plugin.
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
* @param type The config type.
* @return The config implementation.
*/
JSONConfig createLoadableJSONConfig(@NotNull String configName,
LoadableConfig createLoadableConfig(@NotNull String configName,
@NotNull PluginLike plugin,
@NotNull String subDirectoryPath,
@NotNull Class<?> source);
@NotNull Class<?> source,
@NotNull ConfigType type);
/**
* Yaml loadable config.
*
* @param configName The name of the config
* @param plugin The plugin.
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
* @return The config implementation.
*/
Config createLoadableYamlConfig(@NotNull String configName,
@NotNull PluginLike plugin,
@NotNull String subDirectoryPath,
@NotNull Class<?> source);
/**
* Yaml config.
* Create config.
*
* @param config The handle.
* @return The config implementation.
*/
Config createYamlConfig(@NotNull YamlConfiguration config);
Config createConfig(@NotNull YamlConfiguration config);
/**
* JSON config.
* Create config.
*
* @param values The values.
* @return The config implementation.
*/
JSONConfig createJSONConfig(@NotNull Map<String, Object> values);
Config createConfig(@NotNull Map<String, Object> values);
/**
* Create config.
*
* @param contents The file contents.
* @param type The type.
* @return The config implementation.
*/
Config createConfig(@NotNull String contents,
@NotNull ConfigType type);
}

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core.config.wrapper;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.util.StringUtils;
import org.jetbrains.annotations.NotNull;
@@ -15,6 +16,7 @@ import java.util.List;
*
* @param <T> The type of the handle.
*/
@SuppressWarnings("MethodDoesntCallSuperMethod")
public abstract class ConfigWrapper<T extends Config> implements Config {
/**
* Configs from eco have an internal implementation,
@@ -173,11 +175,26 @@ 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();
}
@Override
public @NotNull ConfigType getType() {
return handle.getType();
}
/**
* Get the handle.
*

View File

@@ -0,0 +1,53 @@
package com.willfp.eco.core.config.wrapper;
import com.willfp.eco.core.config.interfaces.LoadableConfig;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
/**
* Wrapper to handle the backend loadable yaml config implementations.
*/
public abstract class LoadableConfigWrapper extends ConfigWrapper<LoadableConfig> implements LoadableConfig {
/**
* Create a config wrapper.
*
* @param handle The handle.
*/
protected LoadableConfigWrapper(@NotNull final LoadableConfig handle) {
super(handle);
}
@Override
public void createFile() {
this.getHandle().createFile();
}
@Override
public String getResourcePath() {
return this.getHandle().getResourcePath();
}
@Override
public void save() throws IOException {
this.getHandle().save();
}
@Override
public File getConfigFile() {
return this.getHandle().getConfigFile();
}
@Override
public String getName() {
return this.getHandle().getName();
}
@Override
public @Nullable YamlConfiguration getBukkitHandle() {
return this.getHandle().getBukkitHandle();
}
}

View File

@@ -3,6 +3,7 @@ package com.willfp.eco.core.config.yaml;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
import org.jetbrains.annotations.NotNull;
@@ -10,7 +11,12 @@ import org.jetbrains.annotations.NotNull;
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
* <p>
* Automatically updates.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class YamlBaseConfig extends LoadableYamlConfigWrapper {
/**
* @param configName The name of the config
@@ -23,12 +29,14 @@ public abstract class YamlBaseConfig extends LoadableYamlConfigWrapper {
@NotNull final PluginLike plugin,
@NotNull final String... updateBlacklist) {
super(
Eco.getHandler().getConfigFactory().createUpdatableYamlConfig(
Eco.getHandler().getConfigFactory().createUpdatableConfig(
configName,
plugin,
"",
plugin.getClass(),
removeUnused, updateBlacklist
removeUnused,
ConfigType.YAML,
updateBlacklist
)
);
}
@@ -42,12 +50,13 @@ public abstract class YamlBaseConfig extends LoadableYamlConfigWrapper {
final boolean removeUnused,
@NotNull final PluginLike plugin) {
super(
Eco.getHandler().getConfigFactory().createUpdatableYamlConfig(
Eco.getHandler().getConfigFactory().createUpdatableConfig(
configName,
plugin,
"",
plugin.getClass(),
removeUnused
removeUnused,
ConfigType.YAML
)
);
}

View File

@@ -3,6 +3,7 @@ package com.willfp.eco.core.config.yaml;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
import org.jetbrains.annotations.NotNull;
@@ -14,7 +15,12 @@ import org.jetbrains.annotations.NotNull;
* </ul>
* <p>
* Automatically updates.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class YamlExtendableConfig extends LoadableYamlConfigWrapper {
/**
* @param configName The name of the config
@@ -31,16 +37,18 @@ public abstract class YamlExtendableConfig extends LoadableYamlConfigWrapper {
@NotNull final String subDirectoryPath,
@NotNull final String... updateBlacklist) {
super(
Eco.getHandler().getConfigFactory().createUpdatableYamlConfig(
Eco.getHandler().getConfigFactory().createUpdatableConfig(
configName,
plugin,
subDirectoryPath,
source,
removeUnused,
ConfigType.YAML,
updateBlacklist
)
);
}
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.

View File

@@ -3,12 +3,18 @@ package com.willfp.eco.core.config.yaml;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
import org.jetbrains.annotations.NotNull;
/**
* Non-updatable yaml config that exists within a plugin jar.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class YamlStaticBaseConfig extends LoadableYamlConfigWrapper {
/**
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
@@ -20,7 +26,7 @@ public abstract class YamlStaticBaseConfig extends LoadableYamlConfigWrapper {
*/
protected YamlStaticBaseConfig(@NotNull final String configName,
@NotNull final PluginLike plugin) {
super(Eco.getHandler().getConfigFactory().createLoadableYamlConfig(configName, plugin, "", plugin.getClass()));
super(Eco.getHandler().getConfigFactory().createLoadableConfig(configName, plugin, "", plugin.getClass(), ConfigType.YAML));
}
/**

View File

@@ -1,6 +1,7 @@
package com.willfp.eco.core.config.yaml;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.yaml.wrapper.YamlConfigWrapper;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
@@ -11,19 +12,31 @@ import java.io.StringReader;
* Config implementation for passing YamlConfigurations.
* <p>
* Does not automatically update.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
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));
super(Eco.getHandler().getConfigFactory().createConfig(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))));
super(Eco.getHandler().getConfigFactory().createConfig(contents, ConfigType.YAML));
}
/**
* Create a new empty transient config.
*/
public YamlTransientConfig() {
super(Eco.getHandler().getConfigFactory().createConfig(YamlConfiguration.loadConfiguration(new StringReader(""))));
}
}

View File

@@ -3,14 +3,21 @@ package com.willfp.eco.core.config.yaml.wrapper;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.config.interfaces.LoadableConfig;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
/**
* Wrapper to handle the backend loadable yaml config implementations.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class LoadableYamlConfigWrapper extends YamlConfigWrapper implements LoadableConfig {
/**
* Create a config wrapper.
@@ -48,4 +55,9 @@ public abstract class LoadableYamlConfigWrapper extends YamlConfigWrapper implem
public String getName() {
return ((LoadableConfig) this.getHandle()).getName();
}
@Override
public @Nullable YamlConfiguration getBukkitHandle() {
return ((LoadableConfig) this.getHandle()).getBukkitHandle();
}
}

View File

@@ -8,7 +8,12 @@ import org.jetbrains.annotations.NotNull;
/**
* Wrapper to handle the backend yaml config implementations.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class YamlConfigWrapper extends ConfigWrapper<Config> implements WrappedYamlConfiguration {
/**
* Create a config wrapper.

View File

@@ -60,7 +60,7 @@ public final class Display {
* @return The ItemStack.
*/
public static ItemStack displayAndFinalize(@NotNull final ItemStack itemStack,
@Nullable final Player player) {
@Nullable final Player player) {
return finalize(display(itemStack, player));
}

View File

@@ -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;
}
}

View File

@@ -1,6 +1,7 @@
package com.willfp.eco.core.events;
import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull;
/**
* Manages listeners for a plugin.
@@ -11,14 +12,14 @@ public interface EventManager {
*
* @param listener The listener to register.
*/
void registerListener(Listener listener);
void registerListener(@NotNull Listener listener);
/**
* Unregister a listener with bukkit.
*
* @param listener The listener to unregister.
*/
void unregisterListener(Listener listener);
void unregisterListener(@NotNull Listener listener);
/**
* Unregister all listeners associated with the plugin.

View File

@@ -7,6 +7,7 @@ import org.apache.commons.lang.Validate;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.logging.Logger;
/**
* An extension is a separate jar file that hooks into the base plugin jar.
@@ -143,6 +144,11 @@ public abstract class Extension implements PluginLike {
return this.plugin.getConfigHandler();
}
@Override
public Logger getLogger() {
return this.plugin.getLogger();
}
/**
* Get the plugin for the extension.
*

View File

@@ -1,7 +1,13 @@
package com.willfp.eco.core.integrations;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;
/**
* An integration loader runs a runnable only if a specific plugin is present on the server.
* <p>
@@ -9,7 +15,15 @@ import org.jetbrains.annotations.NotNull;
*/
public class IntegrationLoader {
/**
* The lambda to be ran if the plugin is present.
* All loaded plugins on the server.
*/
private static final Set<String> LOADED_PLUGINS = Arrays.stream(Bukkit.getPluginManager().getPlugins())
.map(Plugin::getName)
.map(String::toLowerCase)
.collect(Collectors.toSet());
/**
* The lambda to be run if the plugin is present.
*/
private final Runnable runnable;
@@ -22,7 +36,7 @@ public class IntegrationLoader {
* Create a new Integration Loader.
*
* @param pluginName The plugin to require.
* @param onLoad The lambda to be ran if the plugin is present.
* @param onLoad The lambda to be run if the plugin is present.
*/
public IntegrationLoader(@NotNull final String pluginName,
@NotNull final Runnable onLoad) {
@@ -30,6 +44,15 @@ public class IntegrationLoader {
this.pluginName = pluginName;
}
/**
* Load the integration if the specified plugin is present on the server.
*/
public void loadIfPresent() {
if (LOADED_PLUGINS.contains(this.pluginName.toLowerCase())) {
this.load();
}
}
/**
* Load the integration.
*/

View File

@@ -24,7 +24,7 @@ public final class AnticheatManager {
* @param anticheat The anticheat to register.
*/
public static void register(@NotNull final EcoPlugin plugin,
@NotNull final AnticheatWrapper anticheat) {
@NotNull final AnticheatWrapper anticheat) {
if (anticheat instanceof Listener) {
plugin.getEventManager().registerListener((Listener) anticheat);
}

View File

@@ -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));
}

View File

@@ -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,16 @@ 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.
*/
default boolean canPickupItem(@NotNull Player player, @NotNull Location location) {
return true;
}
}

View File

@@ -41,7 +41,7 @@ public final class EconomyManager {
* @return If the player has the amount.
*/
public static boolean hasAmount(@NotNull final OfflinePlayer player,
final double amount) {
final double amount) {
for (EconomyWrapper wrapper : REGISTERED) {
return wrapper.hasAmount(player, amount);
}
@@ -57,7 +57,7 @@ public final class EconomyManager {
* @return If the transaction was a success.
*/
public static boolean giveMoney(@NotNull final OfflinePlayer player,
final double amount) {
final double amount) {
for (EconomyWrapper wrapper : REGISTERED) {
return wrapper.giveMoney(player, amount);
}
@@ -73,7 +73,7 @@ public final class EconomyManager {
* @return If the transaction was a success.
*/
public static boolean removeMoney(@NotNull final OfflinePlayer player,
final double amount) {
final double amount) {
for (EconomyWrapper wrapper : REGISTERED) {
return wrapper.removeMoney(player, amount);
}

View File

@@ -33,7 +33,7 @@ public final class HologramManager {
* @return The hologram.
*/
public static Hologram createHologram(@NotNull final Location location,
@NotNull final List<String> contents) {
@NotNull final List<String> contents) {
for (HologramWrapper wrapper : REGISTERED) {
return wrapper.createHologram(location, contents);
}

View File

@@ -66,7 +66,7 @@ public class CustomItem implements TestableItem {
@Override
public ItemStack getItem() {
return item;
return item.clone();
}
/**

View File

@@ -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;

View File

@@ -0,0 +1,30 @@
package com.willfp.eco.core.items.args;
import org.bukkit.Bukkit;
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(since = "6.16.0", forRemoval = true)
public class ColorArgParser implements LookupArgParser {
/**
* Instantiate arg parser.
*/
public ColorArgParser() {
Bukkit.getLogger().severe("Instantiation of class marked for removal! (" + this.getClass().getName() + "), this will throw an error in a future release!");
}
@Override
public @Nullable Predicate<ItemStack> parseArguments(@NotNull final String[] args,
@NotNull final ItemMeta meta) {
return null;
}
}

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core.items.args;
import org.bukkit.Bukkit;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
@@ -9,49 +10,21 @@ import java.util.function.Predicate;
/**
* Parse custom model data.
*
* @deprecated Moved to internals.
*/
@Deprecated(since = "6.16.0", forRemoval = true)
public class CustomModelDataArgParser implements LookupArgParser {
/**
* Instantiate arg parser.
*/
public CustomModelDataArgParser() {
Bukkit.getLogger().severe("Instantiation of class marked for removal! (" + this.getClass().getName() + "), this will throw an error in a future release!");
}
@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;
}
}

View File

@@ -1,83 +1,30 @@
package com.willfp.eco.core.items.args;
import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.Bukkit;
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(since = "6.16.0", forRemoval = true)
public class EnchantmentArgParser implements LookupArgParser {
/**
* Instantiate arg parser.
*/
public EnchantmentArgParser() {
Bukkit.getLogger().severe("Instantiation of class marked for removal! (" + this.getClass().getName() + "), this will throw an error in a future release!");
}
@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;
}
}

View File

@@ -1,9 +1,8 @@
package com.willfp.eco.core.items.args;
import com.willfp.eco.util.SkullUtils;
import org.bukkit.Bukkit;
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 +10,21 @@ import java.util.function.Predicate;
/**
* Parse skull textures.
*
* @deprecated Moved to internals.
*/
@Deprecated(since = "6.16.0", forRemoval = true)
public class TextureArgParser implements LookupArgParser {
/**
* Instantiate arg parser.
*/
public TextureArgParser() {
Bukkit.getLogger().severe("Instantiation of class marked for removal! (" + this.getClass().getName() + "), this will throw an error in a future release!");
}
@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;
}
}

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core.items.builder;
import com.willfp.eco.core.items.TestableItem;
import com.willfp.eco.util.StringUtils;
import org.apache.commons.lang.Validate;
import org.bukkit.Material;
@@ -43,6 +44,15 @@ public abstract class AbstractItemStackBuilder<T extends ItemMeta, U extends Abs
this(new ItemStack(material));
}
/**
* Create a new ItemStackBuilder to modify an existing item.
*
* @param item The item to start with.
*/
protected AbstractItemStackBuilder(@NotNull final TestableItem item) {
this(item.getItem());
}
/**
* Create a new ItemStackBuilder to modify an existing item.
*

View File

@@ -39,7 +39,7 @@ public class EnchantedBookBuilder extends AbstractItemStackBuilder<EnchantmentSt
* @return The builder.
*/
public EnchantedBookBuilder addStoredEnchantment(@NotNull final Supplier<Enchantment> enchantment,
final Supplier<Integer> level) {
@NotNull final Supplier<Integer> level) {
return this.addStoredEnchantment(enchantment.get(), level.get());
}
}

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core.items.builder;
import com.willfp.eco.core.items.TestableItem;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
@@ -26,4 +27,13 @@ public class ItemStackBuilder extends AbstractItemStackBuilder<ItemMeta, ItemSta
public ItemStackBuilder(@NotNull final ItemStack base) {
super(base);
}
/**
* Create a new ItemStackBuilder to modify an existing item.
*
* @param item The item to start with.
*/
public ItemStackBuilder(@NotNull final TestableItem item) {
super(item);
}
}

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core.items.builder;
import com.willfp.eco.core.items.TestableItem;
import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
@@ -30,6 +31,15 @@ public class LeatherArmorBuilder extends AbstractItemStackBuilder<LeatherArmorMe
super(base);
}
/**
* Create a new ItemStackBuilder to modify an existing item.
*
* @param item The item to start with.
*/
public LeatherArmorBuilder(@NotNull final TestableItem item) {
super(item);
}
/**
* Set leather color.
*

View File

@@ -1,14 +1,12 @@
package com.willfp.eco.core.proxy;
/**
* All proxies must implement this interface.
* <p>
* A proxy is an NMS implementation of a proxy interface.
* <p>
* This allows for cross-version support.
* <p>
* See the core-spigot and core-nms modules of eco to see an example.
* Prior to 6.17.0, all proxies were required to implement this interface,
* however it produced no functionality and was not even used internally.
*
* @deprecated Unused class, not required. Will be removed in a subsequent release.
*/
@Deprecated(since = "6.17.0", forRemoval = true)
public interface AbstractProxy {
}

View File

@@ -13,5 +13,5 @@ public interface ProxyFactory {
* @param <T> The proxy class.
* @return The proxy implementation.
*/
<T extends AbstractProxy> @NotNull T getProxy(@NotNull Class<T> proxyClass);
<T> @NotNull T getProxy(@NotNull Class<T> proxyClass);
}

View File

@@ -79,7 +79,27 @@ public final class Recipes {
@NotNull final String key,
@NotNull final ItemStack output,
@NotNull final List<String> recipeStrings) {
ShapedCraftingRecipe.Builder builder = ShapedCraftingRecipe.builder(plugin, key).setOutput(output);
return createAndRegisterRecipe(plugin, key, output, recipeStrings, null);
}
/**
* Create and register recipe.
*
* @param plugin The plugin.
* @param key The key.
* @param output The output.
* @param recipeStrings The recipe.
* @param permission The permission.
* @return The recipe.
*/
public static CraftingRecipe createAndRegisterRecipe(@NotNull final EcoPlugin plugin,
@NotNull final String key,
@NotNull final ItemStack output,
@NotNull final List<String> recipeStrings,
@Nullable final String permission) {
ShapedCraftingRecipe.Builder builder = ShapedCraftingRecipe.builder(plugin, key)
.setOutput(output)
.setPermission(permission);
for (int i = 0; i < 9; i++) {
builder.setRecipePart(i, Items.lookup(recipeStrings.get(i)));

View File

@@ -4,6 +4,7 @@ import com.willfp.eco.core.items.TestableItem;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@@ -31,6 +32,7 @@ public interface CraftingRecipe {
*
* @return The parts.
*/
@NotNull
List<TestableItem> getParts();
/**
@@ -38,6 +40,7 @@ public interface CraftingRecipe {
*
* @return The key.
*/
@NotNull
NamespacedKey getKey();
/**
@@ -45,6 +48,7 @@ public interface CraftingRecipe {
*
* @return The key.
*/
@NotNull
NamespacedKey getDisplayedKey();
/**
@@ -52,5 +56,16 @@ public interface CraftingRecipe {
*
* @return The output.
*/
@NotNull
ItemStack getOutput();
/**
* Get the recipe permission.
*
* @return The permission.
*/
@Nullable
default String getPermission() {
return null;
}
}

View File

@@ -15,6 +15,7 @@ import org.bukkit.inventory.RecipeChoice;
import org.bukkit.inventory.ShapedRecipe;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
@@ -44,16 +45,23 @@ public final class ShapedCraftingRecipe extends PluginDependent<EcoPlugin> imple
*/
private final ItemStack output;
/**
* The permission.
*/
private final String permission;
private ShapedCraftingRecipe(@NotNull final EcoPlugin plugin,
@NotNull final String key,
@NotNull final List<TestableItem> parts,
@NotNull final ItemStack output) {
@NotNull final ItemStack output,
@Nullable final String permission) {
super(plugin);
this.parts = parts;
this.key = plugin.getNamespacedKeyFactory().create(key);
this.displayedKey = plugin.getNamespacedKeyFactory().create(key + "_displayed");
this.output = output;
this.permission = permission;
}
@Override
@@ -140,6 +148,8 @@ public final class ShapedCraftingRecipe extends PluginDependent<EcoPlugin> imple
*
* @return The parts.
*/
@NotNull
@Override
public List<TestableItem> getParts() {
return this.parts;
}
@@ -149,6 +159,8 @@ public final class ShapedCraftingRecipe extends PluginDependent<EcoPlugin> imple
*
* @return The key.
*/
@NotNull
@Override
public NamespacedKey getKey() {
return this.key;
}
@@ -158,6 +170,8 @@ public final class ShapedCraftingRecipe extends PluginDependent<EcoPlugin> imple
*
* @return The displayed key.
*/
@NotNull
@Override
public NamespacedKey getDisplayedKey() {
return this.displayedKey;
}
@@ -167,10 +181,23 @@ public final class ShapedCraftingRecipe extends PluginDependent<EcoPlugin> imple
*
* @return The output.
*/
@NotNull
@Override
public ItemStack getOutput() {
return this.output;
}
/**
* Get the permission.
*
* @return The permission.
*/
@Nullable
@Override
public String getPermission() {
return permission;
}
/**
* Builder for recipes.
*/
@@ -185,6 +212,11 @@ public final class ShapedCraftingRecipe extends PluginDependent<EcoPlugin> imple
*/
private ItemStack output = null;
/**
* The permission for the recipe.
*/
private String permission = null;
/**
* The key of the recipe.
*/
@@ -244,6 +276,17 @@ public final class ShapedCraftingRecipe extends PluginDependent<EcoPlugin> imple
return this;
}
/**
* Set the permission required to craft the recipe.
*
* @param permission The permission.
* @return The builder.
*/
public Builder setPermission(@Nullable final String permission) {
this.permission = permission;
return this;
}
/**
* Build the recipe.
*
@@ -256,7 +299,7 @@ public final class ShapedCraftingRecipe extends PluginDependent<EcoPlugin> imple
}
}
return new ShapedCraftingRecipe(plugin, key.toLowerCase(), recipeParts, output);
return new ShapedCraftingRecipe(plugin, key.toLowerCase(), recipeParts, output, permission);
}
}
}

View File

@@ -18,6 +18,20 @@ public interface Scheduler {
BukkitTask runLater(@NotNull Runnable runnable,
long ticksLater);
/**
* Run the task after a specified tick delay.
* <p>
* Reordered for better kotlin interop.
*
* @param runnable The lambda to run.
* @param ticksLater The amount of ticks to wait before execution.
* @return The created {@link BukkitTask}.
*/
default BukkitTask runLater(long ticksLater,
@NotNull Runnable runnable) {
return runLater(runnable, ticksLater);
}
/**
* Run the task repeatedly on a timer.
*
@@ -30,6 +44,22 @@ public interface Scheduler {
long delay,
long repeat);
/**
* Run the task repeatedly on a timer.
* <p>
* Reordered for better kotlin interop.
*
* @param runnable The lambda to run.
* @param delay The amount of ticks to wait before the first execution.
* @param repeat The amount of ticks to wait between executions.
* @return The created {@link BukkitTask}.
*/
default BukkitTask runTimer(long delay,
long repeat,
@NotNull Runnable runnable) {
return runTimer(runnable, delay, repeat);
}
/**
* Run the task repeatedly and asynchronously on a timer.
*
@@ -42,6 +72,22 @@ public interface Scheduler {
long delay,
long repeat);
/**
* Run the task repeatedly and asynchronously on a timer.
* <p>
* Reordered for better kotlin interop.
*
* @param runnable The lambda to run.
* @param delay The amount of ticks to wait before the first execution.
* @param repeat The amount of ticks to wait between executions.
* @return The created {@link BukkitTask}.
*/
default BukkitTask runAsyncTimer(long delay,
long repeat,
@NotNull Runnable runnable) {
return runAsyncTimer(runnable, delay, repeat);
}
/**
* Run the task.
*
@@ -70,6 +116,22 @@ public interface Scheduler {
long delay,
long repeat);
/**
* Schedule the task to be ran repeatedly on a timer.
* <p>
* Reordered for better kotlin interop.
*
* @param runnable The lambda to run.
* @param delay The amount of ticks to wait before the first execution.
* @param repeat The amount of ticks to wait between executions.
* @return The id of the task.
*/
default int syncRepeating(long delay,
long repeat,
@NotNull Runnable runnable) {
return syncRepeating(runnable, delay, repeat);
}
/**
* Cancel all running tasks from the linked {@link EcoPlugin}.
*/

View File

@@ -4,6 +4,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -21,8 +22,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);
@@ -56,6 +57,58 @@ public final class ListUtils {
return frequencyMap;
}
/**
* Convert nullable object to either singleton list or empty list.
*
* @param object The object.
* @param <T> The type of the object.
* @return The list.
*/
@NotNull
public static <T> List<T> toSingletonList(@Nullable final T object) {
if (object == null) {
return Collections.emptyList();
} else {
return Collections.singletonList(object);
}
}
/**
* Get element from list or return null if out of bounds.
*
* @param list The list.
* @param index The index.
* @param <T> The type of the list.
* @return The found element, or null if out of bounds.
*/
@Nullable
public static <T> T getOrNull(@Nullable final List<T> list,
final int index) {
if (list == null) {
return null;
}
return index >= 0 && index < list.size() ? list.get(index) : null;
}
/**
* Get if an iterable of strings contains a certain element regardless of case.
*
* @param list The list.
* @param element The element.
* @return If contained.
*/
public static boolean containsIgnoreCase(@NotNull final Iterable<String> list,
@NotNull final String element) {
for (String s : list) {
if (s.equalsIgnoreCase(element)) {
return true;
}
}
return false;
}
private ListUtils() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}

View File

@@ -185,11 +185,23 @@ public final class NumberUtils {
/**
* Get Log base 2 of a number.
*
* @param toLog The number.
* @param a The number.
* @return The result.
*/
public static int log2(final int toLog) {
return (int) (Math.log(toLog) / Math.log(2));
public static int log2(final int a) {
return (int) logBase(a, 2);
}
/**
* Log with a base.
*
* @param a The number.
* @param base The base.
* @return The logarithm.
*/
public static double logBase(final double a,
final double base) {
return Math.log(a) / Math.log(base);
}
/**

View File

@@ -16,30 +16,45 @@ public final class PotionUtils {
public static int getDuration(@NotNull final PotionData data) {
if (data.isExtended()) {
return switch (data.getType()) {
case INSTANT_DAMAGE, INSTANT_HEAL: yield 0;
case POISON, REGEN: yield 1800;
case SLOW_FALLING, WEAKNESS, SLOWNESS: yield 4800;
case TURTLE_MASTER: yield 800;
default: yield 9600;
case INSTANT_DAMAGE, INSTANT_HEAL:
yield 0;
case POISON, REGEN:
yield 1800;
case SLOW_FALLING, WEAKNESS, SLOWNESS:
yield 4800;
case TURTLE_MASTER:
yield 800;
default:
yield 9600;
};
}
if (data.isUpgraded()) {
return switch (data.getType()) {
case INSTANT_DAMAGE, INSTANT_HEAL: yield 0;
case POISON, REGEN: yield 420;
case SLOW_FALLING, WEAKNESS, SLOWNESS: yield 440;
case TURTLE_MASTER: yield 400;
default: yield 1800;
case INSTANT_DAMAGE, INSTANT_HEAL:
yield 0;
case POISON, REGEN:
yield 420;
case SLOW_FALLING, WEAKNESS, SLOWNESS:
yield 440;
case TURTLE_MASTER:
yield 400;
default:
yield 1800;
};
}
return switch (data.getType()) {
case INSTANT_DAMAGE, INSTANT_HEAL: yield 0;
case POISON, REGEN: yield 900;
case SLOW_FALLING, WEAKNESS, SLOWNESS: yield 400;
case TURTLE_MASTER: yield 1800;
default: yield 3600;
case INSTANT_DAMAGE, INSTANT_HEAL:
yield 0;
case POISON, REGEN:
yield 900;
case SLOW_FALLING, WEAKNESS, SLOWNESS:
yield 400;
case TURTLE_MASTER:
yield 1800;
default:
yield 3600;
};
}

View File

@@ -35,7 +35,7 @@ public final class SkullUtils {
* @param base64 The base64 texture.
*/
public static void setSkullTexture(@NotNull final SkullMeta meta,
@NotNull final String base64) {
@NotNull final String base64) {
Validate.isTrue(initialized, "Must be initialized!");
Validate.notNull(metaSetConsumer, "Must be initialized!");
@@ -64,7 +64,7 @@ public final class SkullUtils {
*/
@ApiStatus.Internal
public static void initialize(@NotNull final BiConsumer<SkullMeta, String> function,
@NotNull final Function<SkullMeta, String> function2) {
@NotNull final Function<SkullMeta, String> function2) {
Validate.isTrue(!initialized, "Already initialized!");
metaSetConsumer = function;

View File

@@ -2,6 +2,7 @@ package com.willfp.eco.util;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.gson.JsonSyntaxException;
import com.willfp.eco.core.Prerequisite;
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager;
import net.kyori.adventure.text.Component;
@@ -14,7 +15,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;
@@ -58,6 +59,13 @@ public final class StringUtils {
.hexColors()
.build();
/**
* GSON serializer.
*/
private static final GsonComponentSerializer GSON_COMPONENT_SERIALIZER = GsonComponentSerializer.builder()
.emitLegacyHoverEvent()
.build();
/**
* Color map.
*/
@@ -415,7 +423,7 @@ public final class StringUtils {
if (legacy == null) {
processed = "";
}
return GsonComponentSerializer.gson().serialize(
return GSON_COMPONENT_SERIALIZER.serialize(
Component.empty().decoration(TextDecoration.ITALIC, false).append(
LEGACY_COMPONENT_SERIALIZER.deserialize(processed)
)
@@ -429,10 +437,17 @@ public final class StringUtils {
* @return The legacy string.
*/
@NotNull
public static String jsonToLegacy(@NotNull final String json) {
return LEGACY_COMPONENT_SERIALIZER.serialize(
GsonComponentSerializer.gson().deserialize(json)
);
public static String jsonToLegacy(@Nullable final String json) {
if (json == null || json.isEmpty()) {
return "";
}
try {
Component component = GSON_COMPONENT_SERIALIZER.deserialize(json);
return LEGACY_COMPONENT_SERIALIZER.serialize(component);
} catch (JsonSyntaxException e) {
return json;
}
}
/**

View File

@@ -1,87 +1,93 @@
package com.willfp.eco.internal.config
import com.willfp.eco.core.PluginLike
import com.willfp.eco.core.config.ConfigType
import com.willfp.eco.core.config.interfaces.Config
import com.willfp.eco.core.config.interfaces.JSONConfig
import com.willfp.eco.core.config.interfaces.LoadableConfig
import com.willfp.eco.core.config.wrapper.ConfigFactory
import com.willfp.eco.internal.config.json.EcoJSONConfigSection
import com.willfp.eco.internal.config.json.EcoJSONConfigWrapper
import com.willfp.eco.internal.config.json.EcoLoadableJSONConfig
import com.willfp.eco.internal.config.json.EcoUpdatableJSONConfig
import com.willfp.eco.internal.config.yaml.EcoLoadableYamlConfig
import com.willfp.eco.internal.config.yaml.EcoUpdatableYamlConfig
import com.willfp.eco.internal.config.yaml.EcoYamlConfigSection
import org.bukkit.configuration.file.YamlConfiguration
import java.io.StringReader
class EcoConfigFactory : ConfigFactory {
override fun createUpdatableYamlConfig(
configName: String,
plugin: PluginLike,
subDirectoryPath: String,
source: Class<*>,
removeUnused: Boolean,
vararg updateBlacklist: String
): Config {
return EcoUpdatableYamlConfig(
configName,
plugin,
subDirectoryPath,
source,
removeUnused,
*updateBlacklist
)
}
override fun createUpdatableJSONConfig(
configName: String,
plugin: PluginLike,
subDirectoryPath: String,
source: Class<*>,
removeUnused: Boolean,
vararg updateBlacklist: String
): JSONConfig {
return EcoUpdatableJSONConfig(
configName,
plugin,
subDirectoryPath,
source,
removeUnused,
*updateBlacklist
)
}
override fun createLoadableJSONConfig(
configName: String,
plugin: PluginLike,
subDirectoryPath: String,
source: Class<*>
): JSONConfig {
return EcoLoadableJSONConfig(
configName,
plugin,
subDirectoryPath,
source
)
}
override fun createLoadableYamlConfig(
configName: String,
plugin: PluginLike,
subDirectoryPath: String,
source: Class<*>
): Config {
return EcoLoadableYamlConfig(
configName,
plugin,
subDirectoryPath,
source
)
}
override fun createYamlConfig(config: YamlConfiguration): Config {
override fun createConfig(config: YamlConfiguration): Config {
return EcoYamlConfigSection(config)
}
override fun createJSONConfig(values: Map<String, Any>): JSONConfig {
override fun createConfig(values: MutableMap<String, Any>): Config {
return EcoJSONConfigSection(values)
}
override fun createConfig(contents: String, type: ConfigType): Config {
return if (type == ConfigType.JSON) {
@Suppress("UNCHECKED_CAST")
EcoJSONConfigSection(
EcoJSONConfigWrapper.gson.fromJson(
StringReader(contents), Map::class.java
) as MutableMap<String, Any>
)
} else {
EcoYamlConfigSection(YamlConfiguration.loadConfiguration(StringReader(contents)))
}
}
override fun createLoadableConfig(
configName: String,
plugin: PluginLike,
subDirectoryPath: String,
source: Class<*>,
type: ConfigType
): LoadableConfig {
return if (type == ConfigType.JSON) {
EcoLoadableJSONConfig(
configName,
plugin,
subDirectoryPath,
source
)
} else {
EcoLoadableYamlConfig(
configName,
plugin,
subDirectoryPath,
source
)
}
}
override fun createUpdatableConfig(
configName: String,
plugin: PluginLike,
subDirectoryPath: String,
source: Class<*>,
removeUnused: Boolean,
type: ConfigType,
vararg updateBlacklist: String
): LoadableConfig {
return if (type == ConfigType.JSON) {
EcoUpdatableJSONConfig(
configName,
plugin,
subDirectoryPath,
source,
removeUnused,
*updateBlacklist
)
} else {
EcoUpdatableYamlConfig(
configName,
plugin,
subDirectoryPath,
source,
removeUnused,
*updateBlacklist
)
}
}
}

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.internal.config.json
@Suppress("UNCHECKED_CAST")
class EcoJSONConfigSection(values: Map<String, Any?>) : EcoJSONConfigWrapper() {
init {
init(values)

View File

@@ -1,18 +1,24 @@
@file:Suppress("DEPRECATION")
package com.willfp.eco.internal.config.json
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.willfp.eco.core.config.ConfigType
import com.willfp.eco.core.config.interfaces.JSONConfig
import com.willfp.eco.util.StringUtils
import org.bukkit.configuration.file.YamlConfiguration
import java.util.Objects
import java.util.concurrent.ConcurrentHashMap
@Suppress("UNCHECKED_CAST")
open class EcoJSONConfigWrapper : JSONConfig {
val handle: Gson = GsonBuilder()
.setPrettyPrinting()
.disableHtmlEscaping()
.create()
companion object {
val gson: Gson = GsonBuilder()
.setPrettyPrinting()
.disableHtmlEscaping()
.create()
}
val values = ConcurrentHashMap<String, Any?>()
@@ -28,14 +34,14 @@ open class EcoJSONConfigWrapper : JSONConfig {
}
override fun toPlaintext(): String {
return this.handle.toJson(this.values)
return gson.toJson(this.values)
}
override fun has(path: String): Boolean {
return getOfKnownType(path, Any::class.java) != null
}
private fun <T: Any?> getOfKnownType(
private fun <T : Any?> getOfKnownType(
path: String,
clazz: Class<T>
): T? {
@@ -173,7 +179,10 @@ open class EcoJSONConfigWrapper : JSONConfig {
}
override fun getInts(path: String): MutableList<Int> {
return (Objects.requireNonNullElse(getOfKnownType(path, Any::class.java), emptyList<Int>()) as List<Int>).toMutableList()
return (Objects.requireNonNullElse(
getOfKnownType(path, Any::class.java),
emptyList<Int>()
) as List<Int>).toMutableList()
}
override fun getIntsOrNull(path: String): MutableList<Int>? {
@@ -197,7 +206,10 @@ open class EcoJSONConfigWrapper : JSONConfig {
}
override fun getBools(path: String): MutableList<Boolean> {
return (Objects.requireNonNullElse(getOfKnownType(path, Any::class.java), emptyList<Boolean>()) as List<Boolean>).toMutableList()
return (Objects.requireNonNullElse(
getOfKnownType(path, Any::class.java),
emptyList<Boolean>()
) as List<Boolean>).toMutableList()
}
override fun getBoolsOrNull(path: String): MutableList<Boolean>? {
@@ -235,7 +247,10 @@ open class EcoJSONConfigWrapper : JSONConfig {
option: StringUtils.FormatOption
): MutableList<String> {
val strings =
(Objects.requireNonNullElse(getOfKnownType(path, Any::class.java), emptyList<String>()) as List<String>).toMutableList()
(Objects.requireNonNullElse(
getOfKnownType(path, Any::class.java),
emptyList<String>()
) as List<String>).toMutableList()
return if (format) StringUtils.formatList(strings, option) else strings
}
@@ -264,7 +279,10 @@ open class EcoJSONConfigWrapper : JSONConfig {
}
override fun getDoubles(path: String): MutableList<Double> {
return (Objects.requireNonNullElse(getOfKnownType(path, Any::class.java), emptyList<Double>()) as List<Double>).toMutableList()
return (Objects.requireNonNullElse(
getOfKnownType(path, Any::class.java),
emptyList<Double>()
) as List<Double>).toMutableList()
}
override fun getDoublesOrNull(path: String): MutableList<Double>? {
@@ -275,6 +293,10 @@ open class EcoJSONConfigWrapper : JSONConfig {
}
}
override fun getType(): ConfigType {
return ConfigType.JSON
}
override fun clone(): JSONConfig {
return EcoJSONConfigSection(this.values.toMutableMap())
}

View File

@@ -2,6 +2,7 @@ package com.willfp.eco.internal.config.json
import com.willfp.eco.core.PluginLike
import com.willfp.eco.core.config.interfaces.LoadableConfig
import org.bukkit.configuration.file.YamlConfiguration
import java.io.File
import java.io.FileNotFoundException
import java.io.FileOutputStream
@@ -30,7 +31,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 +41,7 @@ open class EcoLoadableJSONConfig(
}
if (!outFile.exists()) {
val out: OutputStream = FileOutputStream(outFile)
inputStream.copyTo(out, 1024)
inputStream.copyTo(out)
out.close()
inputStream.close()
}
@@ -69,7 +70,7 @@ open class EcoLoadableJSONConfig(
@Throws(FileNotFoundException::class)
fun init(file: File) {
super.init(handle.fromJson(FileReader(file), Map::class.java) as MutableMap<String, Any>)
super.init(gson.fromJson(FileReader(file), Map::class.java) as MutableMap<String, Any>)
}
override fun getName(): String {
@@ -80,6 +81,10 @@ open class EcoLoadableJSONConfig(
return configFile
}
override fun getBukkitHandle(): YamlConfiguration? {
return null
}
init {
val directory = File(this.plugin.dataFolder, subDirectoryPath)
if (!directory.exists()) {

View File

@@ -1,3 +1,5 @@
@file:Suppress("DEPRECATION")
package com.willfp.eco.internal.config.yaml
import com.willfp.eco.core.PluginLike
@@ -40,11 +42,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 {
@@ -61,10 +62,6 @@ open class EcoLoadableYamlConfig(
handle.save(getConfigFile())
}
override fun getBukkitHandle(): YamlConfiguration {
return handle
}
override fun getName(): String {
return name
}
@@ -73,6 +70,10 @@ open class EcoLoadableYamlConfig(
return configFile
}
override fun getBukkitHandle(): YamlConfiguration? {
return handle
}
init {
val directory = File(this.plugin.dataFolder, subDirectoryPath)
if (!directory.exists()) {

View File

@@ -1,16 +1,16 @@
package com.willfp.eco.internal.config.yaml
import com.willfp.eco.core.config.ConfigType
import com.willfp.eco.core.config.interfaces.Config
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 +70,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 +90,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 +262,35 @@ 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 getType(): ConfigType {
return ConfigType.JSON
}
override fun clone(): Config {
return EcoYamlConfigSection(
YamlConfiguration.loadConfiguration(

View File

@@ -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
}
}

View File

@@ -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()

View File

@@ -2,7 +2,7 @@ package com.willfp.eco.internal.extensions
import com.google.common.collect.ImmutableSet
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.config.yaml.YamlTransientConfig
import com.willfp.eco.core.config.TransientConfig
import com.willfp.eco.core.extensions.Extension
import com.willfp.eco.core.extensions.ExtensionLoader
import com.willfp.eco.core.extensions.ExtensionMetadata
@@ -54,7 +54,7 @@ class EcoExtensionLoader(
val ymlIn = classLoader.getResourceAsStream("extension.yml")
?: throw MalformedExtensionException("No extension.yml found in " + extensionJar.name)
val extensionYml = YamlTransientConfig(YamlConfiguration.loadConfiguration(InputStreamReader(ymlIn)))
val extensionYml = TransientConfig(YamlConfiguration.loadConfiguration(InputStreamReader(ymlIn)))
val mainClass = extensionYml.getStringOrNull("main")
var name = extensionYml.getStringOrNull("name")

View File

@@ -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)
}
}

View File

@@ -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
}
}

View File

@@ -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
}

View File

@@ -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 -> {}
}
}

View File

@@ -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)
}

View File

@@ -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
)
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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)
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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)
}
}
}

View File

@@ -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
}
}
}

View File

@@ -1,7 +1,6 @@
package com.willfp.eco.internal.proxy
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.proxy.AbstractProxy
import com.willfp.eco.core.proxy.ProxyConstants
import com.willfp.eco.core.proxy.ProxyFactory
import com.willfp.eco.core.proxy.exceptions.ProxyError
@@ -13,9 +12,9 @@ class EcoProxyFactory(
private val plugin: EcoPlugin
) : ProxyFactory {
private val proxyClassLoader: ClassLoader = plugin::class.java.classLoader
private val cache: MutableMap<Class<out AbstractProxy>, AbstractProxy> = IdentityHashMap()
private val cache: MutableMap<Class<out Any>, Any> = IdentityHashMap()
override fun <T : AbstractProxy> getProxy(proxyClass: Class<T>): T {
override fun <T : Any> getProxy(proxyClass: Class<T>): T {
try {
val cachedProxy: T? = attemptCache(proxyClass)
if (cachedProxy != null) {
@@ -53,7 +52,7 @@ class EcoProxyFactory(
}
}
private fun <T : AbstractProxy> attemptCache(proxyClass: Class<T>): T? {
private fun <T : Any> attemptCache(proxyClass: Class<T>): T? {
val proxy = cache[proxyClass] ?: return null
if (proxyClass.isInstance(proxy)) {

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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() {

View File

@@ -1,5 +1,5 @@
plugins {
id("io.papermc.paperweight.userdev") version "1.2.0"
id("io.papermc.paperweight.userdev") version "1.3.3"
}
group = "com.willfp"

View File

@@ -87,33 +87,29 @@ class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemS
override fun getLore(): List<String> {
if (loreCache != null) {
return loreCache as List<String>
}
val lore: MutableList<String> = ArrayList()
for (s in getLoreJSON()) {
lore.add(StringUtils.jsonToLegacy(s))
return loreCache!!
}
val lore = this.getLoreJSON().map { StringUtils.jsonToLegacy(it) }
loreCache = lore
return lore
}
private fun getLoreJSON(): List<String> {
val displayTag = handle.getTagElement("display") ?: return emptyList()
return if (displayTag.contains("Lore")) {
val loreTag = displayTag.getList("Lore", CraftMagicNumbers.NBT.TAG_STRING)
val lore: MutableList<String> = ArrayList(loreTag.size)
for (i in loreTag.indices) {
lore.add(loreTag.getString(i))
}
lore
} else {
emptyList()
if (!displayTag.contains("Lore")) {
return emptyList()
}
val loreTag = displayTag.getList("Lore", CraftMagicNumbers.NBT.TAG_STRING)
val lore = mutableListOf<String>()
for (i in loreTag.indices) {
lore.add(loreTag.getString(i))
}
return lore
}
override fun addItemFlags(vararg hideFlags: ItemFlag) {
@@ -155,11 +151,11 @@ class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemS
private var flagBits: Int
get() =
if (handle.hasTag() && handle.tag!!.contains(
if (handle.hasTag() && handle.tag.contains(
"HideFlags",
99
)
) handle.tag!!.getInt("HideFlags") else 0
) handle.tag.getInt("HideFlags") else 0
set(value) =
handle.orCreateTag.putInt("HideFlags", value)
@@ -180,7 +176,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() {
@@ -188,4 +184,4 @@ class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemS
bukkit.itemMeta = CraftItemStack.asCraftMirror(handle).itemMeta
}
}
}
}

View File

@@ -1,6 +1,16 @@
plugins {
id("io.papermc.paperweight.userdev") version "1.3.3"
}
group = "com.willfp"
version = rootProject.version
dependencies {
implementation(files("./impl.jar"))
paperDevBundle("1.18.1-R0.1-SNAPSHOT")
}
tasks {
build {
dependsOn(reobfJar)
}
}

Binary file not shown.

View File

@@ -0,0 +1,15 @@
package com.willfp.eco.internal.spigot.proxy.v1_18_R1
import com.willfp.eco.internal.spigot.proxy.AutoCraftProxy
import net.minecraft.network.protocol.game.ClientboundPlaceGhostRecipePacket
import net.minecraft.resources.ResourceLocation
class AutoCraft : AutoCraftProxy {
override fun modifyPacket(packet: Any) {
val recipePacket = packet as ClientboundPlaceGhostRecipePacket
val fKey = recipePacket.javaClass.getDeclaredField("b")
fKey.isAccessible = true
val key = fKey[recipePacket] as ResourceLocation
fKey[recipePacket] = ResourceLocation(key.namespace, key.path + "_displayed")
}
}

View File

@@ -0,0 +1,14 @@
package com.willfp.eco.internal.spigot.proxy.v1_18_R1
import com.willfp.eco.internal.spigot.proxy.BlockBreakProxy
import org.bukkit.block.Block
import org.bukkit.entity.Player
class BlockBreak : BlockBreakProxy {
override fun breakBlock(
player: Player,
block: Block
) {
player.breakBlock(block)
}
}

Some files were not shown because too many files have changed in this diff Show More