Compare commits
94 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac10fa46dc | ||
|
|
7c616e64ae | ||
|
|
708f9130c6 | ||
|
|
9118d49c67 | ||
|
|
a1ce72476f | ||
|
|
2cfab99644 | ||
|
|
cc9b3f7710 | ||
|
|
5bfe48c8d9 | ||
|
|
22ff157ffc | ||
|
|
720dbe789c | ||
|
|
b51dd51941 | ||
|
|
f3ffaa4cf6 | ||
|
|
085032e315 | ||
|
|
3d920ee2b4 | ||
|
|
06a04e4375 | ||
|
|
7349f15784 | ||
|
|
a4c77857d5 | ||
|
|
999fafc8df | ||
|
|
0d533850f6 | ||
|
|
569f9cfcb4 | ||
|
|
f0619f2374 | ||
|
|
7e8d97e11d | ||
|
|
d3414f25ad | ||
|
|
f0cf118448 | ||
|
|
297bb10b85 | ||
|
|
751624bc8d | ||
|
|
8b1b15a3e4 | ||
|
|
7fe330bafb | ||
|
|
20584b2a9b | ||
|
|
bd7594a117 | ||
|
|
f1bfa21270 | ||
|
|
01aa1e708a | ||
|
|
8424baa285 | ||
|
|
d9a8d26990 | ||
|
|
4d3eeaaefc | ||
|
|
d54a2b9516 | ||
|
|
f7f12b6255 | ||
|
|
42eb1344a6 | ||
|
|
4c2a8585cc | ||
|
|
8cccc67b0d | ||
|
|
396d74497c | ||
|
|
49602dce04 | ||
|
|
5da811ba74 | ||
|
|
a4d57e21fe | ||
|
|
4b8efdc79f | ||
|
|
610110efde | ||
|
|
a87f675269 | ||
|
|
a371d314b8 | ||
|
|
9a9097adc5 | ||
|
|
0669a57e4b | ||
|
|
692eaf6836 | ||
|
|
7f9052c64d | ||
|
|
55a841b3f5 | ||
|
|
85f02c5ca2 | ||
|
|
74c428b90d | ||
|
|
fd8c67fa66 | ||
|
|
a396754e2e | ||
|
|
6f97f47712 | ||
|
|
d1109e485a | ||
|
|
476e5c7cae | ||
|
|
dc2b7a6fda | ||
|
|
00f18519b0 | ||
|
|
f7ea5fd182 | ||
|
|
70d29c872a | ||
|
|
f79f4a84c3 | ||
|
|
9af63907ef | ||
|
|
c9aa92895b | ||
|
|
c57c824027 | ||
|
|
7cb905e65a | ||
|
|
31a2c7e338 | ||
|
|
1759b52f82 | ||
|
|
ccf93e3a4d | ||
|
|
abd07389ab | ||
|
|
80ad738bb2 | ||
|
|
b01105819a | ||
|
|
a7c08b0731 | ||
|
|
7e4c071698 | ||
|
|
f94f7ead08 | ||
|
|
b21c5bf3a9 | ||
|
|
7a9e8c5c10 | ||
|
|
a6ddbc46ab | ||
|
|
ffaee137d8 | ||
|
|
18d882dac6 | ||
|
|
52841f7f04 | ||
|
|
47b72e9243 | ||
|
|
854a10e8fd | ||
|
|
823ef6477b | ||
|
|
eccb146852 | ||
|
|
d877b707d6 | ||
|
|
bcb7401c74 | ||
|
|
f05c5f3cd6 | ||
|
|
3bd8bccb81 | ||
|
|
6f55787c84 | ||
|
|
eb4dc168fc |
@@ -1,38 +1,7 @@
|
|||||||
# How to contribute to eco
|
# How to contribute to eco
|
||||||
|
|
||||||
## Codestyle
|
Please open any Pull Requests into the `develop` branch or ideally into a new branch for your changes. PRs that go into `master` won't be ignored, but I have to checkout and merge manually, which makes your PR show as being closed.
|
||||||
|
|
||||||
1. The eco checkstyle is in /config/checkstyle.xml
|
Do not write any Kotlin-only APIs; all API components should be written in Java, Kotlin extensions should not have functionality that isn't available in java. The same applies the other way round, do not write any backend code in Java, it should be Kotlin-exclusive.
|
||||||
|
|
||||||
- The pull request must not have any checkstyle issues.
|
If you have any questions about contributing, feel free to ask in the [Discord](https://discord.gg/ZcwpSsE)!
|
||||||
- Every method and field must have a javadoc attached.
|
|
||||||
|
|
||||||
2. Use JetBrains annotations
|
|
||||||
|
|
||||||
- Every parameter should be annotated with @NotNull or @Nullable
|
|
||||||
|
|
||||||
3. Imports
|
|
||||||
|
|
||||||
- No group (*) imports.
|
|
||||||
- No static imports.
|
|
||||||
|
|
||||||
4. Kotlin
|
|
||||||
|
|
||||||
- Kotlin should be the only language used in the backend, java should be the only language used in the frontend.
|
|
||||||
- Kotlin API extensions should only be for creating extension functions and extra niceties that aren't possible in java.
|
|
||||||
Do not write API components in kotlin.
|
|
||||||
- Kotlin code should never be called directly from the frontend Java API. Kotlin API extensions should always rely on
|
|
||||||
java, not the other way round.
|
|
||||||
|
|
||||||
## Dependency Injection
|
|
||||||
|
|
||||||
- eco uses Dependency Injection
|
|
||||||
- Any calls to Eco#getHandler#getEcoPlugin are code smells and should never be used unless **absolutely necessary**.
|
|
||||||
- NamespacedKeys, FixedMetadataValues, Runnables, and Schedules should be managed using AbstractEcoPlugin through DI.
|
|
||||||
- Any DI class should extend PluginDependent where possible. If the class extends another, then you **must** store the
|
|
||||||
plugin instance in a private final variable called **plugin** with a private or protected getter.
|
|
||||||
|
|
||||||
## Other
|
|
||||||
|
|
||||||
- All drops **must** be sent through a DropQueue - calls to World#dropItem will get your PR rejected.
|
|
||||||
- eco is built with java 17.
|
|
||||||
46
README.md
46
README.md
@@ -1,5 +1,5 @@
|
|||||||
# eco
|
# eco
|
||||||
eco is a powerful Spigot development library that simplifies the process of plugin creation and supercharges
|
eco is a powerful Spigot plugin framework that simplifies the process of plugin creation and supercharges
|
||||||
your plugins.
|
your plugins.
|
||||||
It's the engine behind [EcoEnchants](https://polymart.org/resource/490), [Reforges](https://polymart.org/resource/1330),
|
It's the engine behind [EcoEnchants](https://polymart.org/resource/490), [Reforges](https://polymart.org/resource/1330),
|
||||||
[EcoItems](https://polymart.org/resource/1247), [EcoSkills](https://polymart.org/resource/1351),
|
[EcoItems](https://polymart.org/resource/1247), [EcoSkills](https://polymart.org/resource/1351),
|
||||||
@@ -16,30 +16,54 @@ and many more.
|
|||||||
<a href="https://bstats.org/plugin/bukkit/EcoEnchants" alt="bstats players">
|
<a href="https://bstats.org/plugin/bukkit/EcoEnchants" alt="bstats players">
|
||||||
<img src="https://img.shields.io/bstats/players/7666?color=informational"/>
|
<img src="https://img.shields.io/bstats/players/7666?color=informational"/>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://plugins.auxilor.io/" alt="Docs (gitbook)">
|
|
||||||
<img src="https://img.shields.io/badge/docs-gitbook-informational"/>
|
|
||||||
</a>
|
|
||||||
<a href="https://discord.gg/ZcwpSsE/" alt="Discord">
|
<a href="https://discord.gg/ZcwpSsE/" alt="Discord">
|
||||||
<img src="https://img.shields.io/discord/452518336627081236?label=discord&color=informational"/>
|
<img src="https://img.shields.io/discord/452518336627081236?label=discord&color=informational"/>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://github.com/Auxilor/eco/actions/workflows/java-ci.yml" alt="Latest Dev Build">
|
<a href="https://github.com/Auxilor/eco/actions/workflows/java-ci.yml" alt="Latest Dev Build">
|
||||||
<img src="https://img.shields.io/github/workflow/status/Auxilor/eco/Java%20CI/develop?color=informational"/>
|
<img src="https://img.shields.io/github/actions/workflow/status/Auxilor/eco/java-ci.yml?branch=develop&color=informational"/>
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
eco comes packed with all the tools you need in your plugins:
|
||||||
|
|
||||||
|
- Modern command API
|
||||||
|
- Native color parsing with full hex/RGB/MiniMessage support
|
||||||
|
- Yaml/JSON/TOML config system
|
||||||
|
- Persistent data storage API with Yaml/MySQL/MongoDB support
|
||||||
|
- Packet item display system
|
||||||
|
- Entity AI API with near-1:1 NMS mappings
|
||||||
|
- More events
|
||||||
|
- Extension API, essentially plugins for plugins
|
||||||
|
- Fluent dependency injection for NamespacedKey, Metadata values, etc.
|
||||||
|
- Ultra-fast ItemStack reimplementation bypassing ItemMeta
|
||||||
|
- Complete GUI API with pre-made components available from [ecomponent](https://github.com/Auxilor/ecomponent)
|
||||||
|
- Over 30 native integrations for other plugins
|
||||||
|
- First-class custom item support with lookup strings
|
||||||
|
- Math expression parsing via [Crunch](https://github.com/Redempt/Crunch)
|
||||||
|
- Particle lookups
|
||||||
|
- Complete Placeholder API
|
||||||
|
- Price system, supporting economy plugins, XP, Items, etc.
|
||||||
|
- NMS/Version-specific tooling
|
||||||
|
- Custom crafting recipe API with support for stacks and custom items
|
||||||
|
- Native plugin update checking
|
||||||
|
- Native bStats support
|
||||||
|
- Full Kotlin support and native extensions
|
||||||
|
- Tooling to make meta-frameworks, like [libreforge](https://github.com/Auxilor/libreforge)
|
||||||
|
- And much more
|
||||||
|
|
||||||
# For server owners
|
# For server owners
|
||||||
- Requires ProtocolLib to be installed: get the latest version [here](https://www.spigotmc.org/resources/protocollib.1997/)
|
- Requires ProtocolLib to be installed: get the latest version [here](https://www.spigotmc.org/resources/protocollib.1997/)
|
||||||
- Supports 1.17+
|
- Supports 1.17+
|
||||||
|
|
||||||
## Downloads
|
## Downloads
|
||||||
|
|
||||||
- Stable (Recommended): [GitHub](https://github.com/Auxilor/eco/releases), [Polymart](https://polymart.org/resource/eco.773)
|
- Stable: [GitHub](https://github.com/Auxilor/eco/releases), [Polymart](https://polymart.org/resource/eco.773)
|
||||||
- Dev (Not Recommended): [GitHub](https://github.com/Auxilor/eco/actions/workflows/java-ci.yml) (Open latest run and download)
|
- Dev: [GitHub](https://github.com/Auxilor/eco/actions/workflows/java-ci.yml) (Open latest run and download)
|
||||||
|
|
||||||
# For developers
|
# For developers
|
||||||
|
|
||||||
## Javadoc
|
## Javadoc
|
||||||
The 6.45.0 Javadoc can be found [here](https://javadoc.jitpack.io/com/willfp/eco/6.45.0/javadoc/)
|
The 6.49.0 Javadoc can be found [here](https://javadoc.jitpack.io/com/willfp/eco/6.49.0/javadoc/)
|
||||||
|
|
||||||
## Plugin Information
|
## Plugin Information
|
||||||
|
|
||||||
@@ -68,7 +92,7 @@ dependencies {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Replace `Tag` with a release tag for eco, eg `6.45.0`.
|
Replace `Tag` with a release tag for eco, eg `6.49.0`.
|
||||||
|
|
||||||
Maven:
|
Maven:
|
||||||
|
|
||||||
@@ -88,7 +112,7 @@ Maven:
|
|||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
|
|
||||||
Replace `Tag` with a release tag for eco, eg `6.45.0`.
|
Replace `Tag` with a release tag for eco, eg `6.49.0`.
|
||||||
|
|
||||||
## Build locally:
|
## Build locally:
|
||||||
|
|
||||||
@@ -103,7 +127,7 @@ cd eco
|
|||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
*Click here to read [the entire license](https://github.com/Auxilor/eco/blob/master/LICENSE.md).*
|
eco is licensed under GNU GPL3. *Click here to read [the entire license](https://github.com/Auxilor/eco/blob/master/LICENSE.md).*
|
||||||
|
|
||||||
<h1 align="center">
|
<h1 align="center">
|
||||||
Check out our partners!
|
Check out our partners!
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ dependencies {
|
|||||||
implementation(project(path = ":eco-core:core-nms:v1_18_R1", configuration = "reobf"))
|
implementation(project(path = ":eco-core:core-nms:v1_18_R1", configuration = "reobf"))
|
||||||
implementation(project(path = ":eco-core:core-nms:v1_18_R2", configuration = "reobf"))
|
implementation(project(path = ":eco-core:core-nms:v1_18_R2", configuration = "reobf"))
|
||||||
implementation(project(path = ":eco-core:core-nms:v1_19_R1", configuration = "reobf"))
|
implementation(project(path = ":eco-core:core-nms:v1_19_R1", configuration = "reobf"))
|
||||||
|
implementation(project(path = ":eco-core:core-nms:v1_19_R2", configuration = "reobf"))
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
@@ -77,6 +78,8 @@ allprojects {
|
|||||||
|
|
||||||
// LibsDisguises
|
// LibsDisguises
|
||||||
maven("https://repo.md-5.net/content/groups/public/")
|
maven("https://repo.md-5.net/content/groups/public/")
|
||||||
|
|
||||||
|
maven("https://repo.techscode.com/repository/maven-releases/")
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
package com.willfp.eco.core;
|
package com.willfp.eco.core;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.command.CommandBase;
|
||||||
|
import com.willfp.eco.core.command.PluginCommandBase;
|
||||||
|
import com.willfp.eco.core.command.impl.PluginCommand;
|
||||||
import com.willfp.eco.core.config.ConfigType;
|
import com.willfp.eco.core.config.ConfigType;
|
||||||
import com.willfp.eco.core.config.interfaces.Config;
|
import com.willfp.eco.core.config.interfaces.Config;
|
||||||
import com.willfp.eco.core.config.interfaces.LoadableConfig;
|
import com.willfp.eco.core.config.interfaces.LoadableConfig;
|
||||||
@@ -29,6 +32,7 @@ import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
|||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.command.CommandMap;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Mob;
|
import org.bukkit.entity.Mob;
|
||||||
@@ -47,18 +51,18 @@ import java.util.UUID;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the instance of eco for bridging between the frontend
|
* Holds the instance of eco for bridging between the frontend and backend.
|
||||||
* and backend.
|
|
||||||
* <p>
|
* <p>
|
||||||
* <strong>Do not use this in your plugins!</strong> It can and will contain
|
* <strong>Do not use this in your plugins!</strong> It can and will contain
|
||||||
* breaking changes between minor versions and even patches, and you will create
|
* breaking changes between minor versions and even patches, and you will create compatibility
|
||||||
* compatibility issues by. All parts of this have been abstracted
|
* issues by. All parts of this have been abstracted into logically named API components that you
|
||||||
* into logically named API components that you can use.
|
* can use.
|
||||||
*
|
*
|
||||||
* @see Eco#get()
|
* @see Eco#get()
|
||||||
*/
|
*/
|
||||||
@ApiStatus.Internal
|
@ApiStatus.Internal
|
||||||
public interface Eco {
|
public interface Eco {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a scheduler.
|
* Create a scheduler.
|
||||||
*
|
*
|
||||||
@@ -71,7 +75,7 @@ public interface Eco {
|
|||||||
/**
|
/**
|
||||||
* Create an event manager.
|
* Create an event manager.
|
||||||
*
|
*
|
||||||
* @param plugin The plugin.
|
* @param plugin The plugin.F
|
||||||
* @return The event manager.
|
* @return The event manager.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -155,6 +159,40 @@ public interface Eco {
|
|||||||
@NotNull
|
@NotNull
|
||||||
EcoPlugin getEcoPlugin();
|
EcoPlugin getEcoPlugin();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create PluginCommandBase implementation of {@link PluginCommand}.
|
||||||
|
*
|
||||||
|
* @param parentDelegate the enclosing class of this implementation.
|
||||||
|
* @param plugin the plugin.
|
||||||
|
* @param name the name of the command.
|
||||||
|
* @param permission the permission of the command.
|
||||||
|
* @param playersOnly if the command is players only.
|
||||||
|
* @return The PluginCommandBase implementation
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
PluginCommandBase createPluginCommand(@NotNull CommandBase parentDelegate,
|
||||||
|
@NotNull EcoPlugin plugin,
|
||||||
|
@NotNull String name,
|
||||||
|
@NotNull String permission,
|
||||||
|
boolean playersOnly);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create CommandBase implementation of {@link com.willfp.eco.core.command.impl.Subcommand Subcommand}.
|
||||||
|
*
|
||||||
|
* @param parentDelegate the enclosing class of this implementation.
|
||||||
|
* @param plugin the plugin.
|
||||||
|
* @param name the name of the command.
|
||||||
|
* @param permission the permission of the command.
|
||||||
|
* @param playersOnly if the command is players only.
|
||||||
|
* @return The CommandBase implementation
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
CommandBase createSubcommand(@NotNull CommandBase parentDelegate,
|
||||||
|
@NotNull EcoPlugin plugin,
|
||||||
|
@NotNull String name,
|
||||||
|
@NotNull String permission,
|
||||||
|
boolean playersOnly);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updatable config.
|
* Updatable config.
|
||||||
*
|
*
|
||||||
@@ -376,9 +414,8 @@ public interface Eco {
|
|||||||
/**
|
/**
|
||||||
* Create a {@link NamespacedKey} quickly
|
* Create a {@link NamespacedKey} quickly
|
||||||
* <p>
|
* <p>
|
||||||
* Bypasses the constructor, allowing for the creation of invalid keys,
|
* Bypasses the constructor, allowing for the creation of invalid keys, therefore this is
|
||||||
* therefore this is considered unsafe and should only be called after
|
* considered unsafe and should only be called after the key has been confirmed to be valid.
|
||||||
* the key has been confirmed to be valid.
|
|
||||||
*
|
*
|
||||||
* @param namespace The namespace.
|
* @param namespace The namespace.
|
||||||
* @param key The key.
|
* @param key The key.
|
||||||
@@ -511,8 +548,21 @@ public interface Eco {
|
|||||||
void syncCommands();
|
void syncCommands();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the instance of eco; the bridge between the api frontend
|
* Get the command map.
|
||||||
* and the implementation backend.
|
*
|
||||||
|
* @return The command map.
|
||||||
|
*/
|
||||||
|
@NotNull CommandMap getCommandMap();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregister a command.
|
||||||
|
*
|
||||||
|
* @param command The command.
|
||||||
|
*/
|
||||||
|
void unregisterCommand(@NotNull final PluginCommand command);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the instance of eco; the bridge between the api frontend and the implementation backend.
|
||||||
*
|
*
|
||||||
* @return The instance of eco.
|
* @return The instance of eco.
|
||||||
*/
|
*/
|
||||||
@@ -526,6 +576,7 @@ public interface Eco {
|
|||||||
*/
|
*/
|
||||||
@ApiStatus.Internal
|
@ApiStatus.Internal
|
||||||
final class Instance {
|
final class Instance {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instance of eco.
|
* Instance of eco.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -344,6 +344,13 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
|||||||
this.configHandler = Eco.get().createConfigHandler(this);
|
this.configHandler = Eco.get().createConfigHandler(this);
|
||||||
|
|
||||||
this.langYml = this.createLangYml();
|
this.langYml = this.createLangYml();
|
||||||
|
|
||||||
|
if (!this.langYml.isValid()) {
|
||||||
|
this.getLogger().warning("Notify plugin authors " + String.join(", ", this.getDescription().getAuthors()) + " that");
|
||||||
|
this.getLogger().warning("they are missing crucial lang.yml keys! They can be found");
|
||||||
|
this.getLogger().warning("in the LangYml class.");
|
||||||
|
}
|
||||||
|
|
||||||
this.configYml = this.createConfigYml();
|
this.configYml = this.createConfigYml();
|
||||||
|
|
||||||
Eco.get().addNewPlugin(this);
|
Eco.get().addNewPlugin(this);
|
||||||
@@ -699,7 +706,15 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
|||||||
* @return lang.yml.
|
* @return lang.yml.
|
||||||
*/
|
*/
|
||||||
protected LangYml createLangYml() {
|
protected LangYml createLangYml() {
|
||||||
|
try {
|
||||||
return new LangYml(this);
|
return new LangYml(this);
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
this.getLogger().severe("Failed to load lang.yml!");
|
||||||
|
this.getLogger().severe("For the developer of this plugin: make sure you have a lang.yml");
|
||||||
|
e.printStackTrace();
|
||||||
|
Bukkit.getPluginManager().disablePlugin(this);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -710,7 +725,15 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
|||||||
* @return config.yml.
|
* @return config.yml.
|
||||||
*/
|
*/
|
||||||
protected ConfigYml createConfigYml() {
|
protected ConfigYml createConfigYml() {
|
||||||
|
try {
|
||||||
return new ConfigYml(this);
|
return new ConfigYml(this);
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
this.getLogger().severe("Failed to load config.yml!");
|
||||||
|
this.getLogger().severe("For the developer of this plugin: make sure you have a config.yml");
|
||||||
|
e.printStackTrace();
|
||||||
|
Bukkit.getPluginManager().disablePlugin(this);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ public final class PluginProps {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Create new props from known values.
|
* Create new props from known values.
|
||||||
*
|
* <p>
|
||||||
* Marked as internal as this method will break whenever the properties themselves
|
* Marked as internal as this method will break whenever the properties themselves
|
||||||
* are updated (e.g. if a new property is added) - so to prevent any potential
|
* are updated (e.g. if a new property is added) - so to prevent any potential
|
||||||
* backwards-compatibility bugs, this method cannot be invoked outside eco itself.
|
* backwards-compatibility bugs, this method cannot be invoked outside eco itself.
|
||||||
|
|||||||
@@ -70,7 +70,10 @@ public class Prerequisite {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Requires the server to be running an implementation of BungeeCord.
|
* Requires the server to be running an implementation of BungeeCord.
|
||||||
|
*
|
||||||
|
* @deprecated This will never return true.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(since = "6.49.0", forRemoval = true)
|
||||||
public static final Prerequisite HAS_BUNGEECORD = new Prerequisite(
|
public static final Prerequisite HAS_BUNGEECORD = new Prerequisite(
|
||||||
() -> ClassUtils.exists("net.md_5.bungee.api.event.ServerConnectedEvent"),
|
() -> ClassUtils.exists("net.md_5.bungee.api.event.ServerConnectedEvent"),
|
||||||
"Requires server to be running BungeeCord (or a fork)"
|
"Requires server to be running BungeeCord (or a fork)"
|
||||||
@@ -78,7 +81,10 @@ public class Prerequisite {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Requires the server to be running an implementation of Velocity.
|
* Requires the server to be running an implementation of Velocity.
|
||||||
|
*
|
||||||
|
* @deprecated This will never return true.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(since = "6.49.0", forRemoval = true)
|
||||||
public static final Prerequisite HAS_VELOCITY = new Prerequisite(
|
public static final Prerequisite HAS_VELOCITY = new Prerequisite(
|
||||||
() -> ClassUtils.exists("com.velocitypowered.api.event.player.ServerConnectedEvent"),
|
() -> ClassUtils.exists("com.velocitypowered.api.event.player.ServerConnectedEvent"),
|
||||||
"Requires server to be running Velocity (or a fork)"
|
"Requires server to be running Velocity (or a fork)"
|
||||||
|
|||||||
@@ -1,32 +1,37 @@
|
|||||||
package com.willfp.eco.core.command;
|
package com.willfp.eco.core.command;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
import com.willfp.eco.core.EcoPlugin;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.OfflinePlayer;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for all command implementations.
|
* Generic interface for commands.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("removal")
|
@SuppressWarnings("null")
|
||||||
public interface CommandBase {
|
public interface CommandBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get command name.
|
* Get command name.
|
||||||
*
|
*
|
||||||
* @return The name.
|
* @return The name.
|
||||||
*/
|
*/
|
||||||
String getName();
|
@NotNull String getName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get command permission.
|
* Get command permission.
|
||||||
*
|
*
|
||||||
* @return The permission.
|
* @return The permission.
|
||||||
*/
|
*/
|
||||||
String getPermission();
|
@NotNull String getPermission();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If only players can execute the command.
|
* If only players can execute the command.
|
||||||
@@ -41,110 +46,237 @@ public interface CommandBase {
|
|||||||
* @param command The subcommand.
|
* @param command The subcommand.
|
||||||
* @return The parent command.
|
* @return The parent command.
|
||||||
*/
|
*/
|
||||||
CommandBase addSubcommand(@NotNull CommandBase command);
|
@NotNull CommandBase addSubcommand(@NotNull CommandBase command);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the subcommands of the command.
|
||||||
|
*
|
||||||
|
* @return The subcommands.
|
||||||
|
*/
|
||||||
|
@NotNull List<CommandBase> getSubcommands();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Intended for returning the enclosing CommandBase,
|
||||||
|
* when this instance is serving as the delegate command base.
|
||||||
|
*
|
||||||
|
* @return the wrapping object of this delegate.
|
||||||
|
*/
|
||||||
|
default @NotNull CommandBase getWrapped() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle command execution.
|
* Handle command execution.
|
||||||
|
* <p>
|
||||||
|
* This will always be called on command execution.
|
||||||
*
|
*
|
||||||
* @param sender The sender.
|
* @param sender The sender.
|
||||||
* @param args The args.
|
* @param args The args.
|
||||||
|
* @throws NotificationException naturally, this is handled as a part of the command system.
|
||||||
*/
|
*/
|
||||||
default void onExecute(@NotNull CommandSender sender,
|
default void onExecute(@NotNull final CommandSender sender, @NotNull final List<String> args) throws NotificationException {
|
||||||
@NotNull List<String> args) {
|
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle command execution from players.
|
* Handle command execution from players.
|
||||||
|
* <p>
|
||||||
|
* This will only be called if the sender is a player.
|
||||||
*
|
*
|
||||||
* @param sender The sender.
|
* @param sender The sender.
|
||||||
* @param args The args.
|
* @param args The args.
|
||||||
|
* @throws NotificationException naturally, this is handled as a part of the command system.
|
||||||
*/
|
*/
|
||||||
default void onExecute(@NotNull Player sender,
|
default void onExecute(@NotNull final Player sender, @NotNull final List<String> args) throws NotificationException {
|
||||||
@NotNull List<String> args) {
|
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle tab completion.
|
* Handle tab completion.
|
||||||
|
* <p>
|
||||||
|
* This will always be called on tab completion.
|
||||||
*
|
*
|
||||||
* @param sender The sender.
|
* @param sender The sender.
|
||||||
* @param args The args.
|
* @param args The args.
|
||||||
* @return The results.
|
* @return The results.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
default List<String> tabComplete(@NotNull CommandSender sender,
|
default List<String> tabComplete(@NotNull final CommandSender sender, @NotNull final List<String> args) {
|
||||||
@NotNull List<String> args) {
|
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle tab completion.
|
* Handle tab completion.
|
||||||
|
* <p>
|
||||||
|
* This will only be called if the sender is a player.
|
||||||
*
|
*
|
||||||
* @param sender The sender.
|
* @param sender The sender.
|
||||||
* @param args The args.
|
* @param args The args.
|
||||||
* @return The results.
|
* @return The results.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
default List<String> tabComplete(@NotNull Player sender,
|
default List<String> tabComplete(@NotNull final Player sender, @NotNull final List<String> args) {
|
||||||
@NotNull List<String> args) {
|
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws an {@link NotificationException} relating to a specific lang.yml key.
|
||||||
|
* <p>
|
||||||
|
* This is automatically handled with eco, and should not be surrounded by a
|
||||||
|
* try/catch block.
|
||||||
|
*
|
||||||
|
* @param key The lang.yml key for the message to be sent.
|
||||||
|
* @throws NotificationException always.
|
||||||
|
*/
|
||||||
|
default void notify(@NotNull final String key) throws NotificationException {
|
||||||
|
throw new NotificationException(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws an {@link NotificationException} relating to a specific lang.yml key
|
||||||
|
* if the passed object is null.
|
||||||
|
* <p>
|
||||||
|
* This is automatically handled with eco, and should not be surrounded by a
|
||||||
|
* try/catch block.
|
||||||
|
*
|
||||||
|
* @param obj The object to test.
|
||||||
|
* @param key The lang.yml key for the message to be sent.
|
||||||
|
* @param <T> The object type.
|
||||||
|
* @return Returns the object, definitely not-null.
|
||||||
|
* @throws NotificationException If the object is null.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
default <T> T notifyNull(@Nullable final T obj,
|
||||||
|
@NotNull final String key) throws NotificationException {
|
||||||
|
if (Objects.isNull(obj)) {
|
||||||
|
notify(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Objects.requireNonNull(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws an {@link NotificationException} relating to a specific lang.yml key
|
||||||
|
* if the passed object doesn't match the predicate.
|
||||||
|
* <p>
|
||||||
|
* This is automatically handled with eco, and should not be surrounded by a
|
||||||
|
* try/catch block.
|
||||||
|
*
|
||||||
|
* @param obj The object to test.
|
||||||
|
* @param key The lang.yml key for the message to be sent.
|
||||||
|
* @param predicate The predicate to test the object against.
|
||||||
|
* @param <T> The type of the object.
|
||||||
|
* @return Returns the object, definitely not-null.
|
||||||
|
* @throws NotificationException If the object doesn't satisfy the predicate.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
default <T> T notifyFalse(@NotNull final T obj,
|
||||||
|
@NotNull final String key,
|
||||||
|
@NotNull final Predicate<T> predicate) throws NotificationException {
|
||||||
|
notifyFalse(predicate.test(obj), key);
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws an {@link NotificationException} relating to a specific lang.yml key
|
||||||
|
* if a condition is false.
|
||||||
|
* <p>
|
||||||
|
* This is automatically handled with eco, and should not be surrounded by a
|
||||||
|
* try/catch block.
|
||||||
|
*
|
||||||
|
* @param condition The condition to test.
|
||||||
|
* @param key The lang.yml key for the message to be sent.
|
||||||
|
* @return True.
|
||||||
|
* @throws NotificationException If the condition is false.
|
||||||
|
*/
|
||||||
|
default boolean notifyFalse(final boolean condition,
|
||||||
|
@NotNull final String key) throws NotificationException {
|
||||||
|
if (!condition) {
|
||||||
|
notify(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws an {@link NotificationException} relating to a specific lang.yml key
|
||||||
|
* if the passed string doesn't relate to a currently online player.
|
||||||
|
* <p>
|
||||||
|
* This is automatically handled with eco, and should not be surrounded by a
|
||||||
|
* try/catch block.
|
||||||
|
*
|
||||||
|
* @param playerName The player name.
|
||||||
|
* @param key The lang.yml key for the message to be sent.
|
||||||
|
* @return Returns the player, definitely not-null.
|
||||||
|
* @throws NotificationException If the player name is invalid.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
default Player notifyPlayerRequired(@Nullable final String playerName, @NotNull final String key) throws NotificationException {
|
||||||
|
if (playerName == null) {
|
||||||
|
notify(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert playerName != null;
|
||||||
|
|
||||||
|
final Player player = Bukkit.getPlayer(playerName);
|
||||||
|
|
||||||
|
notifyNull(player, key);
|
||||||
|
|
||||||
|
return Objects.requireNonNull(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws an {@link NotificationException} relating to a specific lang.yml key
|
||||||
|
* if the passed string doesn't relate to a player on the server.
|
||||||
|
* <p>
|
||||||
|
* This is automatically handled with eco, and should not be surrounded by a
|
||||||
|
* try/catch block.
|
||||||
|
*
|
||||||
|
* @param playerName The player name.
|
||||||
|
* @param key The lang.yml key for the message to be sent.
|
||||||
|
* @return Returns the offline player, definitely not-null.
|
||||||
|
* @throws NotificationException If the player name is invalid.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
default OfflinePlayer notifyOfflinePlayerRequired(@Nullable final String playerName,
|
||||||
|
@NotNull final String key) throws NotificationException {
|
||||||
|
if (playerName == null) {
|
||||||
|
notify(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert playerName != null;
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation") final OfflinePlayer player = Bukkit.getOfflinePlayer(playerName);
|
||||||
|
|
||||||
|
boolean hasPlayedBefore = player.hasPlayedBefore() || player.isOnline();
|
||||||
|
|
||||||
|
notifyFalse(!hasPlayedBefore, key);
|
||||||
|
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws an exception containing a langYml key if player doesn't have permission.
|
||||||
|
*
|
||||||
|
* @param player The player.
|
||||||
|
* @param permission The permission.
|
||||||
|
* @param key The lang.yml key for the message to be sent.
|
||||||
|
* @return The player.
|
||||||
|
* @throws NotificationException If the player doesn't have the required permission.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
default Player notifyPermissionRequired(@NotNull final Player player,
|
||||||
|
@NotNull final String permission,
|
||||||
|
@NotNull final String key) throws NotificationException {
|
||||||
|
return notifyFalse(player, key, p -> p.hasPermission(permission));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the plugin.
|
* Get the plugin.
|
||||||
*
|
*
|
||||||
* @return The plugin.
|
* @return The plugin.
|
||||||
*/
|
*/
|
||||||
EcoPlugin getPlugin();
|
EcoPlugin getPlugin();
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the handler.
|
|
||||||
*
|
|
||||||
* @return The handler.
|
|
||||||
* @see CommandHandler
|
|
||||||
* @deprecated Use {@link CommandBase#onExecute(CommandSender, List)} instead.
|
|
||||||
*/
|
|
||||||
@Deprecated(forRemoval = true)
|
|
||||||
default CommandHandler getHandler() {
|
|
||||||
return (a, b) -> {
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the handler.
|
|
||||||
*
|
|
||||||
* @param handler The handler.
|
|
||||||
* @see CommandHandler
|
|
||||||
* @deprecated Handlers have been deprecated.
|
|
||||||
*/
|
|
||||||
@Deprecated(forRemoval = true)
|
|
||||||
default void setHandler(@NotNull final CommandHandler handler) {
|
|
||||||
// Do nothing.
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the tab completer.
|
|
||||||
*
|
|
||||||
* @return The tab completer.
|
|
||||||
* @see TabCompleteHandler
|
|
||||||
* @deprecated Use {@link CommandBase#tabComplete(CommandSender, List)} instead.
|
|
||||||
*/
|
|
||||||
@Deprecated(forRemoval = true)
|
|
||||||
default TabCompleteHandler getTabCompleter() {
|
|
||||||
return (a, b) -> ImmutableList.of();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the tab completer.
|
|
||||||
*
|
|
||||||
* @param handler The handler.
|
|
||||||
* @see TabCompleteHandler
|
|
||||||
* @deprecated Handlers have been deprecated.
|
|
||||||
*/
|
|
||||||
@Deprecated(forRemoval = true)
|
|
||||||
default void setTabCompleter(@NotNull final TabCompleteHandler handler) {
|
|
||||||
// Do nothing.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
package com.willfp.eco.core.command;
|
|
||||||
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
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", forRemoval = true)
|
|
||||||
public interface CommandHandler {
|
|
||||||
/**
|
|
||||||
* The code to be called on execution.
|
|
||||||
*
|
|
||||||
* @param sender The sender.
|
|
||||||
* @param args The arguments.
|
|
||||||
*/
|
|
||||||
void onExecute(@NotNull CommandSender sender,
|
|
||||||
@NotNull List<String> args);
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package com.willfp.eco.core.command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A notification exception is thrown when {@link org.bukkit.command.CommandSender}s don't
|
||||||
|
* specify valid arguments in commands.
|
||||||
|
* <p>
|
||||||
|
* Methods in eco that throw this will contain automatic handling and thus
|
||||||
|
* should not be surrounded by try / catch blocks.
|
||||||
|
*/
|
||||||
|
public class NotificationException extends Exception {
|
||||||
|
/**
|
||||||
|
* The key for the lang.yml message to be sent.
|
||||||
|
*/
|
||||||
|
private final String key;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a notification exception.
|
||||||
|
*
|
||||||
|
* @param key The lang key of the notification.
|
||||||
|
*/
|
||||||
|
public NotificationException(String key) {
|
||||||
|
super(key);
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the lang key.
|
||||||
|
*
|
||||||
|
* @return The lang key.
|
||||||
|
*/
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package com.willfp.eco.core.command;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plugin command bases can be registered directly with the server,
|
||||||
|
* this essentially functions as the interface that is implemented generically
|
||||||
|
* via {@link com.willfp.eco.core.command.impl.PluginCommand}.
|
||||||
|
*/
|
||||||
|
public interface PluginCommandBase extends CommandBase {
|
||||||
|
/**
|
||||||
|
* Register the PluginCommandBase to the bukkit commandMap.
|
||||||
|
*/
|
||||||
|
void register();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregister the PluginCommandBase from the bukkit commandMap.
|
||||||
|
*/
|
||||||
|
void unregister();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get aliases. Leave null if this command is from plugin.yml.
|
||||||
|
*
|
||||||
|
* @return The aliases.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
default List<String> getAliases() {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get description.
|
||||||
|
*
|
||||||
|
* @return The description.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
default String getDescription() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package com.willfp.eco.core.command;
|
|
||||||
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
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", forRemoval = true)
|
|
||||||
public interface TabCompleteHandler {
|
|
||||||
/**
|
|
||||||
* Handle Tab Completion.
|
|
||||||
*
|
|
||||||
* @param sender The sender.
|
|
||||||
* @param args The arguments.
|
|
||||||
* @return The tab completion results.
|
|
||||||
*/
|
|
||||||
List<String> tabComplete(@NotNull CommandSender sender,
|
|
||||||
@NotNull List<String> args);
|
|
||||||
}
|
|
||||||
@@ -6,13 +6,15 @@ import org.bukkit.command.PluginIdentifiableCommand;
|
|||||||
import org.bukkit.command.TabCompleter;
|
import org.bukkit.command.TabCompleter;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delegates a bukkit command to an eco command (for registrations).
|
* Delegates a bukkit command to an eco command (for registrations).
|
||||||
|
*
|
||||||
|
* @deprecated Internal command implementations have been removed from the API.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(forRemoval = true, since = "6.49.0")
|
||||||
public final class DelegatedBukkitCommand extends Command implements TabCompleter, PluginIdentifiableCommand {
|
public final class DelegatedBukkitCommand extends Command implements TabCompleter, PluginIdentifiableCommand {
|
||||||
/**
|
/**
|
||||||
* The delegate command.
|
* The delegate command.
|
||||||
@@ -34,7 +36,7 @@ public final class DelegatedBukkitCommand extends Command implements TabComplete
|
|||||||
public boolean execute(@NotNull final CommandSender commandSender,
|
public boolean execute(@NotNull final CommandSender commandSender,
|
||||||
@NotNull final String label,
|
@NotNull final String label,
|
||||||
@NotNull final String[] args) {
|
@NotNull final String[] args) {
|
||||||
return delegate.onCommand(commandSender, this, label, args);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -42,7 +44,7 @@ public final class DelegatedBukkitCommand extends Command implements TabComplete
|
|||||||
@NotNull final Command command,
|
@NotNull final Command command,
|
||||||
@NotNull final String label,
|
@NotNull final String label,
|
||||||
@NotNull final String[] args) {
|
@NotNull final String[] args) {
|
||||||
return delegate.onTabComplete(commandSender, command, label, args);
|
return List.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -51,9 +53,8 @@ public final class DelegatedBukkitCommand extends Command implements TabComplete
|
|||||||
return this.delegate.getPlugin();
|
return this.delegate.getPlugin();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
@Override
|
||||||
public String getPermission() {
|
public @NotNull String getPermission() {
|
||||||
return this.delegate.getPermission();
|
return this.delegate.getPermission();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,294 +0,0 @@
|
|||||||
package com.willfp.eco.core.command.impl;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
|
||||||
import com.willfp.eco.core.command.CommandBase;
|
|
||||||
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;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract class for commands that can be handled.
|
|
||||||
* <p>
|
|
||||||
* Handled commands have a method to pass in raw input from bukkit commands
|
|
||||||
* in order to execute the command-specific code. It's essentially an internal
|
|
||||||
* layer, hence why it's a package-private class.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings({"DeprecatedIsStillUsed", "removal"})
|
|
||||||
abstract class HandledCommand implements CommandBase {
|
|
||||||
/**
|
|
||||||
* The plugin.
|
|
||||||
*/
|
|
||||||
private final EcoPlugin plugin;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the command.
|
|
||||||
*/
|
|
||||||
private final String name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The permission required to execute the command.
|
|
||||||
* <p>
|
|
||||||
* Written out as a string for flexibility with subclasses.
|
|
||||||
*/
|
|
||||||
private final String permission;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Should the command only be allowed to be executed by players?
|
|
||||||
* <p>
|
|
||||||
* In other worlds, only allowed to be executed by console.
|
|
||||||
*/
|
|
||||||
private final boolean playersOnly;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The actual code to be executed in the command.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
@Nullable
|
|
||||||
private com.willfp.eco.core.command.CommandHandler handler = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The tab completion code to be executed in the command.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
@Nullable
|
|
||||||
private com.willfp.eco.core.command.TabCompleteHandler tabCompleter = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* All subcommands for the command.
|
|
||||||
*/
|
|
||||||
private final List<CommandBase> subcommands;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new command.
|
|
||||||
* <p>
|
|
||||||
* The name cannot be the same as an existing command as this will conflict.
|
|
||||||
*
|
|
||||||
* @param plugin Instance of a plugin.
|
|
||||||
* @param name The name used in execution.
|
|
||||||
* @param permission The permission required to execute the command.
|
|
||||||
* @param playersOnly If only players should be able to execute this command.
|
|
||||||
*/
|
|
||||||
HandledCommand(@NotNull final EcoPlugin plugin,
|
|
||||||
@NotNull final String name,
|
|
||||||
@NotNull final String permission,
|
|
||||||
final boolean playersOnly) {
|
|
||||||
this.plugin = plugin;
|
|
||||||
this.name = name;
|
|
||||||
this.permission = permission;
|
|
||||||
this.playersOnly = playersOnly;
|
|
||||||
this.subcommands = new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a subcommand to the command.
|
|
||||||
*
|
|
||||||
* @param subcommand The subcommand.
|
|
||||||
* @return The parent command.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final CommandBase addSubcommand(@NotNull final CommandBase subcommand) {
|
|
||||||
subcommands.add(subcommand);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the plugin.
|
|
||||||
*
|
|
||||||
* @return The plugin.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public EcoPlugin getPlugin() {
|
|
||||||
return this.plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle the command.
|
|
||||||
*
|
|
||||||
* @param sender The sender.
|
|
||||||
* @param args The arguments.
|
|
||||||
*/
|
|
||||||
protected final void handle(@NotNull final CommandSender sender,
|
|
||||||
@NotNull final String[] args) {
|
|
||||||
if (!canExecute(sender, this, this.getPlugin())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.length > 0) {
|
|
||||||
for (CommandBase subcommand : this.getSubcommands()) {
|
|
||||||
if (subcommand.getName().equalsIgnoreCase(args[0])) {
|
|
||||||
if (!canExecute(sender, subcommand, this.getPlugin())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
((HandledCommand) subcommand).handle(sender, Arrays.copyOfRange(args, 1, args.length));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.isPlayersOnly() && !(sender instanceof Player)) {
|
|
||||||
sender.sendMessage(this.getPlugin().getLangYml().getMessage("not-player"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.getHandler() != null) {
|
|
||||||
this.getHandler().onExecute(sender, Arrays.asList(args));
|
|
||||||
} else {
|
|
||||||
this.onExecute(sender, Arrays.asList(args));
|
|
||||||
if (sender instanceof Player player) {
|
|
||||||
this.onExecute(player, Arrays.asList(args));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle the tab completion.
|
|
||||||
*
|
|
||||||
* @param sender The sender.
|
|
||||||
* @param args The arguments.
|
|
||||||
* @return The tab completion results.
|
|
||||||
*/
|
|
||||||
protected final List<String> handleTabCompletion(@NotNull final CommandSender sender,
|
|
||||||
@NotNull final String[] args) {
|
|
||||||
|
|
||||||
if (!sender.hasPermission(this.getPermission())) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.length == 1) {
|
|
||||||
List<String> completions = new ArrayList<>();
|
|
||||||
|
|
||||||
StringUtil.copyPartialMatches(
|
|
||||||
args[0],
|
|
||||||
this.getSubcommands().stream()
|
|
||||||
.filter(subCommand -> sender.hasPermission(subCommand.getPermission()))
|
|
||||||
.map(CommandBase::getName)
|
|
||||||
.collect(Collectors.toList()),
|
|
||||||
completions
|
|
||||||
);
|
|
||||||
|
|
||||||
Collections.sort(completions);
|
|
||||||
|
|
||||||
if (!completions.isEmpty()) {
|
|
||||||
return completions;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.length >= 2) {
|
|
||||||
HandledCommand command = null;
|
|
||||||
|
|
||||||
for (CommandBase subcommand : this.getSubcommands()) {
|
|
||||||
if (!sender.hasPermission(subcommand.getPermission())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args[0].equalsIgnoreCase(subcommand.getName())) {
|
|
||||||
command = (HandledCommand) subcommand;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (command != null) {
|
|
||||||
return command.handleTabCompletion(sender, Arrays.copyOfRange(args, 1, args.length));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.getTabCompleter() != null) {
|
|
||||||
return this.getTabCompleter().tabComplete(sender, Arrays.asList(args));
|
|
||||||
} else {
|
|
||||||
List<String> completions = new ArrayList<>(this.tabComplete(sender, Arrays.asList(args)));
|
|
||||||
if (sender instanceof Player player) {
|
|
||||||
completions.addAll(this.tabComplete(player, Arrays.asList(args)));
|
|
||||||
}
|
|
||||||
return completions;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If a sender can execute the command.
|
|
||||||
*
|
|
||||||
* @param sender The sender.
|
|
||||||
* @param command The command.
|
|
||||||
* @param plugin The plugin.
|
|
||||||
* @return If the sender can execute.
|
|
||||||
*/
|
|
||||||
public static boolean canExecute(@NotNull final CommandSender sender,
|
|
||||||
@NotNull final CommandBase command,
|
|
||||||
@NotNull final EcoPlugin plugin) {
|
|
||||||
if (!sender.hasPermission(command.getPermission()) && sender instanceof Player) {
|
|
||||||
sender.sendMessage(plugin.getLangYml().getNoPermission());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the command name.
|
|
||||||
*
|
|
||||||
* @return The name.
|
|
||||||
*/
|
|
||||||
public String getName() {
|
|
||||||
return this.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the permission required to execute the command.
|
|
||||||
*
|
|
||||||
* @return The permission.
|
|
||||||
*/
|
|
||||||
public String getPermission() {
|
|
||||||
return this.permission;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get if the command can only be executed by players.
|
|
||||||
*
|
|
||||||
* @return If players only.
|
|
||||||
*/
|
|
||||||
public boolean isPlayersOnly() {
|
|
||||||
return this.playersOnly;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the subcommands of the command.
|
|
||||||
*
|
|
||||||
* @return The subcommands.
|
|
||||||
*/
|
|
||||||
public List<CommandBase> getSubcommands() {
|
|
||||||
return this.subcommands;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated(forRemoval = true)
|
|
||||||
@Override
|
|
||||||
public @Nullable com.willfp.eco.core.command.CommandHandler getHandler() {
|
|
||||||
return this.handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated(forRemoval = true)
|
|
||||||
@Override
|
|
||||||
public @Nullable com.willfp.eco.core.command.TabCompleteHandler getTabCompleter() {
|
|
||||||
return this.tabCompleter;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated(forRemoval = true)
|
|
||||||
@Override
|
|
||||||
public void setHandler(@Nullable final com.willfp.eco.core.command.CommandHandler handler) {
|
|
||||||
this.handler = handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated(forRemoval = true)
|
|
||||||
@Override
|
|
||||||
public void setTabCompleter(@Nullable final com.willfp.eco.core.command.TabCompleteHandler tabCompleter) {
|
|
||||||
this.tabCompleter = tabCompleter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,29 +2,27 @@ package com.willfp.eco.core.command.impl;
|
|||||||
|
|
||||||
import com.willfp.eco.core.Eco;
|
import com.willfp.eco.core.Eco;
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
import com.willfp.eco.core.EcoPlugin;
|
||||||
import org.bukkit.Bukkit;
|
import com.willfp.eco.core.command.CommandBase;
|
||||||
import org.bukkit.command.Command;
|
import com.willfp.eco.core.command.PluginCommandBase;
|
||||||
import org.bukkit.command.CommandExecutor;
|
|
||||||
import org.bukkit.command.CommandMap;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.command.TabCompleter;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
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
|
||||||
* they function as the base command, e.g. {@code /ecoenchants} would be a base command, with each
|
* command, e.g. {@code /ecoenchants} would be a base command, with each subsequent argument
|
||||||
* subsequent argument functioning as subcommands.
|
* functioning as subcommands.
|
||||||
* <p>
|
* <p>
|
||||||
* The command will not be registered until register() is called.
|
* The command will not be registered until register() is called.
|
||||||
* <p>
|
* <p>
|
||||||
* The name cannot be the same as an existing command as this will conflict.
|
* The name cannot be the same as an existing command as this will conflict.
|
||||||
*/
|
*/
|
||||||
public abstract class PluginCommand extends HandledCommand implements CommandExecutor, TabCompleter {
|
public abstract class PluginCommand implements PluginCommandBase {
|
||||||
|
/**
|
||||||
|
* The delegate command.
|
||||||
|
*/
|
||||||
|
private final PluginCommandBase delegate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new command.
|
* Create a new command.
|
||||||
*
|
*
|
||||||
@@ -37,128 +35,51 @@ public abstract class PluginCommand extends HandledCommand implements CommandExe
|
|||||||
@NotNull final String name,
|
@NotNull final String name,
|
||||||
@NotNull final String permission,
|
@NotNull final String permission,
|
||||||
final boolean playersOnly) {
|
final boolean playersOnly) {
|
||||||
super(plugin, name, permission, playersOnly);
|
this.delegate = Eco.get().createPluginCommand(this, plugin, name, permission, playersOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers the command with the server,
|
|
||||||
*/
|
|
||||||
public final void register() {
|
|
||||||
org.bukkit.command.PluginCommand command = Bukkit.getPluginCommand(this.getName());
|
|
||||||
if (command != null) {
|
|
||||||
command.setExecutor(this);
|
|
||||||
command.setTabCompleter(this);
|
|
||||||
|
|
||||||
if (this.getDescription() != null) {
|
|
||||||
command.setDescription(this.getDescription());
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> aliases = new ArrayList<>(command.getAliases());
|
|
||||||
aliases.addAll(this.getAliases());
|
|
||||||
command.setAliases(aliases);
|
|
||||||
} else {
|
|
||||||
this.unregister();
|
|
||||||
|
|
||||||
CommandMap commandMap = getCommandMap();
|
|
||||||
|
|
||||||
commandMap.register(this.getPlugin().getName().toLowerCase(), new DelegatedBukkitCommand(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
Eco.get().syncCommands();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unregisters the command from the server.
|
|
||||||
*/
|
|
||||||
public final void unregister() {
|
|
||||||
CommandMap commandMap = getCommandMap();
|
|
||||||
|
|
||||||
Command found = commandMap.getCommand(this.getName());
|
|
||||||
if (found != null) {
|
|
||||||
found.unregister(commandMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
Eco.get().syncCommands();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get aliases. Leave null if this command is from plugin.yml.
|
|
||||||
*
|
|
||||||
* @return The aliases.
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
public List<String> getAliases() {
|
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get description.
|
|
||||||
*
|
|
||||||
* @return The description.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
public String getDescription() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal implementation used to clean up boilerplate.
|
|
||||||
* Used for parity with {@link CommandExecutor#onCommand(CommandSender, Command, String, String[])}.
|
|
||||||
*
|
|
||||||
* @param sender The executor of the command.
|
|
||||||
* @param command The bukkit command.
|
|
||||||
* @param label The name of the executed command.
|
|
||||||
* @param args The arguments of the command (anything after the physical command name)
|
|
||||||
* @return If the command was processed by the linked {@link EcoPlugin}
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public final boolean onCommand(@NotNull final CommandSender sender,
|
public @NotNull String getName() {
|
||||||
@NotNull final Command command,
|
return delegate.getName();
|
||||||
@NotNull final String label,
|
|
||||||
@NotNull final String[] args) {
|
|
||||||
if (!command.getName().equalsIgnoreCase(this.getName())) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.handle(sender, args);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal implementation used to clean up boilerplate.
|
|
||||||
* Used for parity with {@link TabCompleter#onTabComplete(CommandSender, Command, String, String[])}.
|
|
||||||
*
|
|
||||||
* @param sender The executor of the command.
|
|
||||||
* @param command The bukkit command.
|
|
||||||
* @param label The name of the executed command.
|
|
||||||
* @param args The arguments of the command (anything after the physical command name).
|
|
||||||
* @return The list of tab-completions.
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable List<String> onTabComplete(@NotNull final CommandSender sender,
|
public @NotNull String getPermission() {
|
||||||
@NotNull final Command command,
|
return delegate.getPermission();
|
||||||
@NotNull final String label,
|
|
||||||
@NotNull final String[] args) {
|
|
||||||
if (!command.getName().equalsIgnoreCase(this.getName())) {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.handleTabCompletion(sender, args);
|
@Override
|
||||||
|
public boolean isPlayersOnly() {
|
||||||
|
return delegate.isPlayersOnly();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Get the internal server CommandMap.
|
public @NotNull CommandBase addSubcommand(@NotNull CommandBase command) {
|
||||||
*
|
return delegate.addSubcommand(command);
|
||||||
* @return The CommandMap.
|
}
|
||||||
*/
|
|
||||||
public static CommandMap getCommandMap() {
|
@Override
|
||||||
try {
|
public @NotNull List<CommandBase> getSubcommands() {
|
||||||
Field field = Bukkit.getServer().getClass().getDeclaredField("commandMap");
|
return delegate.getSubcommands();
|
||||||
field.setAccessible(true);
|
}
|
||||||
return (CommandMap) field.get(Bukkit.getServer());
|
|
||||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
@Override
|
||||||
throw new NullPointerException("Command map wasn't found!");
|
public @NotNull CommandBase getWrapped() {
|
||||||
}
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void register() {
|
||||||
|
delegate.register();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unregister() {
|
||||||
|
delegate.unregister();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EcoPlugin getPlugin() {
|
||||||
|
return delegate.getPlugin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,21 @@
|
|||||||
package com.willfp.eco.core.command.impl;
|
package com.willfp.eco.core.command.impl;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.Eco;
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
import com.willfp.eco.core.EcoPlugin;
|
||||||
import com.willfp.eco.core.command.CommandBase;
|
import com.willfp.eco.core.command.CommandBase;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subcommands can be added to PluginCommands or to other Subcommands.
|
* A command implementation that must exist as a subcommand (i.e. cannot be registered directly).
|
||||||
*/
|
*/
|
||||||
public abstract class Subcommand extends HandledCommand {
|
public abstract class Subcommand implements CommandBase {
|
||||||
|
/**
|
||||||
|
* The delegate command.
|
||||||
|
*/
|
||||||
|
private final CommandBase delegate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create subcommand.
|
* Create subcommand.
|
||||||
*
|
*
|
||||||
@@ -20,7 +28,7 @@ public abstract class Subcommand extends HandledCommand {
|
|||||||
@NotNull final String name,
|
@NotNull final String name,
|
||||||
@NotNull final String permission,
|
@NotNull final String permission,
|
||||||
final boolean playersOnly) {
|
final boolean playersOnly) {
|
||||||
super(plugin, name, permission, playersOnly);
|
this.delegate = Eco.get().createSubcommand(this, plugin, name, permission, playersOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -33,6 +41,41 @@ public abstract class Subcommand extends HandledCommand {
|
|||||||
protected Subcommand(@NotNull final EcoPlugin plugin,
|
protected Subcommand(@NotNull final EcoPlugin plugin,
|
||||||
@NotNull final String name,
|
@NotNull final String name,
|
||||||
@NotNull final CommandBase parent) {
|
@NotNull final CommandBase parent) {
|
||||||
super(plugin, name, parent.getPermission(), parent.isPlayersOnly());
|
this(plugin, name, parent.getPermission(), parent.isPlayersOnly());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getName() {
|
||||||
|
return delegate.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getPermission() {
|
||||||
|
return delegate.getPermission();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPlayersOnly() {
|
||||||
|
return delegate.isPlayersOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull CommandBase addSubcommand(@NotNull CommandBase command) {
|
||||||
|
return delegate.addSubcommand(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull List<CommandBase> getSubcommands() {
|
||||||
|
return delegate.getSubcommands();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull CommandBase getWrapped() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EcoPlugin getPlugin() {
|
||||||
|
return delegate.getPlugin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,32 @@ import com.willfp.eco.core.config.ConfigType;
|
|||||||
import com.willfp.eco.util.StringUtils;
|
import com.willfp.eco.util.StringUtils;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default plugin lang.yml.
|
* Default plugin lang.yml.
|
||||||
*/
|
*/
|
||||||
public class LangYml extends BaseConfig {
|
public class LangYml extends BaseConfig {
|
||||||
|
/**
|
||||||
|
* The messages key.
|
||||||
|
*/
|
||||||
|
public static final String KEY_MESSAGES = "messages";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The prefix key.
|
||||||
|
*/
|
||||||
|
public static final String KEY_PREFIX = "messages.prefix";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The no permission key.
|
||||||
|
*/
|
||||||
|
public static final String KEY_NO_PERMISSION = "messages.no-permission";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The not player key.
|
||||||
|
*/
|
||||||
|
public static final String KEY_NOT_PLAYER = "messages.not-player";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lang.yml.
|
* Lang.yml.
|
||||||
*
|
*
|
||||||
@@ -19,13 +41,31 @@ public class LangYml extends BaseConfig {
|
|||||||
super("lang", plugin, false, ConfigType.YAML);
|
super("lang", plugin, false, ConfigType.YAML);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lang.yml requires certain keys to be present.
|
||||||
|
* <p>
|
||||||
|
* If the lang.yml does not contain these keys, it is considered to be
|
||||||
|
* invalid and thus will show a warning in console.
|
||||||
|
*
|
||||||
|
* @return If valid.
|
||||||
|
*/
|
||||||
|
public boolean isValid() {
|
||||||
|
for (String key : List.of(KEY_MESSAGES, KEY_PREFIX, KEY_NO_PERMISSION, KEY_NOT_PLAYER)) {
|
||||||
|
if (!this.has(key)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the prefix for messages in chat.
|
* Get the prefix for messages in chat.
|
||||||
*
|
*
|
||||||
* @return The prefix.
|
* @return The prefix.
|
||||||
*/
|
*/
|
||||||
public String getPrefix() {
|
public String getPrefix() {
|
||||||
return this.getFormattedString("messages.prefix");
|
return this.getFormattedString(KEY_PREFIX);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -34,7 +74,7 @@ public class LangYml extends BaseConfig {
|
|||||||
* @return The message.
|
* @return The message.
|
||||||
*/
|
*/
|
||||||
public String getNoPermission() {
|
public String getNoPermission() {
|
||||||
return getPrefix() + this.getFormattedString("messages.no-permission");
|
return getPrefix() + this.getFormattedString(KEY_NO_PERMISSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -56,6 +96,6 @@ public class LangYml extends BaseConfig {
|
|||||||
*/
|
*/
|
||||||
public String getMessage(@NotNull final String message,
|
public String getMessage(@NotNull final String message,
|
||||||
@NotNull final StringUtils.FormatOption option) {
|
@NotNull final StringUtils.FormatOption option) {
|
||||||
return getPrefix() + this.getFormattedString("messages." + message, option);
|
return getPrefix() + this.getFormattedString(KEY_MESSAGES + "." + message, option);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ public final class PersistentDataKey<T> {
|
|||||||
if (this == o) {
|
if (this == o) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!(o instanceof PersistentDataKey that)) {
|
if (!(o instanceof PersistentDataKey<?> that)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return Objects.equals(this.getKey(), that.getKey());
|
return Objects.equals(this.getKey(), that.getKey());
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ public final class PersistentDataKeyType<T> {
|
|||||||
if (this == that) {
|
if (this == that) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!(that instanceof PersistentDataKeyType type)) {
|
if (!(that instanceof PersistentDataKeyType<?> type)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return Objects.equals(this.name, type.name);
|
return Objects.equals(this.name, type.name);
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ public interface MenuBuilder extends PageBuilder {
|
|||||||
* @return The builder.
|
* @return The builder.
|
||||||
*/
|
*/
|
||||||
default MenuBuilder maxPages(@NotNull final Function<Player, Integer> pages) {
|
default MenuBuilder maxPages(@NotNull final Function<Player, Integer> pages) {
|
||||||
return onRender((player, menu) -> menu.setState(player, Page.MAX_PAGE_KEY, pages.apply(player)));
|
return this.onRender((player, menu) -> menu.setState(player, Page.MAX_PAGE_KEY, pages.apply(player)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
package com.willfp.eco.core.gui.slot;
|
package com.willfp.eco.core.gui.slot;
|
||||||
|
|
||||||
import com.willfp.eco.core.config.interfaces.Config;
|
import com.willfp.eco.core.config.interfaces.Config;
|
||||||
|
import com.willfp.eco.core.fast.FastItemStack;
|
||||||
import com.willfp.eco.core.gui.slot.functional.SlotHandler;
|
import com.willfp.eco.core.gui.slot.functional.SlotHandler;
|
||||||
import com.willfp.eco.core.items.Items;
|
import com.willfp.eco.core.items.Items;
|
||||||
import com.willfp.eco.util.StringUtils;
|
import com.willfp.eco.util.StringUtils;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.inventory.ClickType;
|
import org.bukkit.event.inventory.ClickType;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -37,7 +39,25 @@ public class ConfigSlot extends CustomSlot {
|
|||||||
public ConfigSlot(@NotNull final Config config) {
|
public ConfigSlot(@NotNull final Config config) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
|
||||||
SlotBuilder builder = Slot.builder(Items.lookup(config.getString("item")));
|
ItemStack item = Items.lookup(config.getString("item")).getItem();
|
||||||
|
|
||||||
|
SlotBuilder builder = Slot.builder((player, menu) -> {
|
||||||
|
if (!config.has("lore")) {
|
||||||
|
return item;
|
||||||
|
} else {
|
||||||
|
FastItemStack fast = FastItemStack.wrap(item.clone());
|
||||||
|
List<String> newLore = new ArrayList<>(fast.getLore());
|
||||||
|
newLore.addAll(
|
||||||
|
StringUtils.formatList(
|
||||||
|
config.getStrings("lore"),
|
||||||
|
player,
|
||||||
|
StringUtils.FormatOption.WITH_PLACEHOLDERS
|
||||||
|
)
|
||||||
|
);
|
||||||
|
fast.setLore(newLore);
|
||||||
|
return fast.unwrap();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
for (ClickType clickType : ClickType.values()) {
|
for (ClickType clickType : ClickType.values()) {
|
||||||
builder.onClick(
|
builder.onClick(
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.willfp.eco.core.gui.menu.Menu;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for custom slot implementations.
|
* Base class for custom slot implementations.
|
||||||
@@ -31,7 +32,7 @@ public abstract class CustomSlot implements Slot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull ItemStack getItemStack(@NotNull final Player player) {
|
public final @NotNull ItemStack getItemStack(@NotNull final Player player) {
|
||||||
if (delegate == null) {
|
if (delegate == null) {
|
||||||
throw new IllegalStateException("Custom Slot was not initialized!");
|
throw new IllegalStateException("Custom Slot was not initialized!");
|
||||||
}
|
}
|
||||||
@@ -40,7 +41,7 @@ public abstract class CustomSlot implements Slot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCaptive(@NotNull final Player player,
|
public final boolean isCaptive(@NotNull final Player player,
|
||||||
@NotNull final Menu menu) {
|
@NotNull final Menu menu) {
|
||||||
if (delegate == null) {
|
if (delegate == null) {
|
||||||
throw new IllegalStateException("Custom Slot was not initialized!");
|
throw new IllegalStateException("Custom Slot was not initialized!");
|
||||||
@@ -50,7 +51,18 @@ public abstract class CustomSlot implements Slot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCaptiveFromEmpty() {
|
public final boolean isAllowedCaptive(@NotNull final Player player,
|
||||||
|
@NotNull final Menu menu,
|
||||||
|
@Nullable final ItemStack itemStack) {
|
||||||
|
if (delegate == null) {
|
||||||
|
throw new IllegalStateException("Custom Slot was not initialized!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return delegate.isAllowedCaptive(player, menu, itemStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean isCaptiveFromEmpty() {
|
||||||
if (delegate == null) {
|
if (delegate == null) {
|
||||||
throw new IllegalStateException("Custom Slot was not initialized!");
|
throw new IllegalStateException("Custom Slot was not initialized!");
|
||||||
}
|
}
|
||||||
@@ -59,7 +71,7 @@ public abstract class CustomSlot implements Slot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final Slot getActionableSlot(@NotNull final Player player,
|
public final @NotNull Slot getActionableSlot(@NotNull final Player player,
|
||||||
@NotNull final Menu menu) {
|
@NotNull final Menu menu) {
|
||||||
return delegate;
|
return delegate;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import org.bukkit.Material;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for custom slot implementations.
|
* Base class for custom slot implementations.
|
||||||
@@ -34,11 +35,18 @@ public abstract class ReactiveSlot implements Slot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCaptive(@NotNull final Player player,
|
public final boolean isCaptive(@NotNull final Player player,
|
||||||
@NotNull final Menu menu) {
|
@NotNull final Menu menu) {
|
||||||
return getSlot(player, menu).isCaptive(player, menu);
|
return getSlot(player, menu).isCaptive(player, menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean isAllowedCaptive(@NotNull final Player player,
|
||||||
|
@NotNull final Menu menu,
|
||||||
|
@Nullable final ItemStack itemStack) {
|
||||||
|
return getSlot(player, menu).isAllowedCaptive(player, menu, itemStack);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final @NotNull Slot getActionableSlot(@NotNull final Player player,
|
public final @NotNull Slot getActionableSlot(@NotNull final Player player,
|
||||||
@NotNull final Menu menu) {
|
@NotNull final Menu menu) {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import org.bukkit.Material;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
@@ -45,6 +46,20 @@ public interface Slot extends GUIComponent {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the slot allows a certain item to be placed in it.
|
||||||
|
*
|
||||||
|
* @param player The player.
|
||||||
|
* @param menu The menu.
|
||||||
|
* @param itemStack The item; use null if the item is unknown.
|
||||||
|
* @return If captive.
|
||||||
|
*/
|
||||||
|
default boolean isAllowedCaptive(@NotNull final Player player,
|
||||||
|
@NotNull final Menu menu,
|
||||||
|
@Nullable final ItemStack itemStack) {
|
||||||
|
return this.isCaptive(player, menu);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the actionable slot to be shown.
|
* Get the actionable slot to be shown.
|
||||||
* <p>
|
* <p>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.willfp.eco.core.gui.slot;
|
package com.willfp.eco.core.gui.slot;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.gui.slot.functional.CaptiveFilter;
|
||||||
import com.willfp.eco.core.gui.slot.functional.SlotHandler;
|
import com.willfp.eco.core.gui.slot.functional.SlotHandler;
|
||||||
import com.willfp.eco.core.gui.slot.functional.SlotModifier;
|
import com.willfp.eco.core.gui.slot.functional.SlotModifier;
|
||||||
import com.willfp.eco.core.gui.slot.functional.SlotUpdater;
|
import com.willfp.eco.core.gui.slot.functional.SlotUpdater;
|
||||||
@@ -143,7 +144,17 @@ public interface SlotBuilder {
|
|||||||
* @param predicate The predicate. Returns true when the slot should not be captive.
|
* @param predicate The predicate. Returns true when the slot should not be captive.
|
||||||
* @return The builder.
|
* @return The builder.
|
||||||
*/
|
*/
|
||||||
SlotBuilder notCaptiveFor(@NotNull Predicate<Player> predicate);
|
SlotBuilder notCaptiveFor(@NotNull final Predicate<Player> predicate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a whitelist for allowed captive items.
|
||||||
|
*
|
||||||
|
* @param filter The filter.
|
||||||
|
* @return The builder.
|
||||||
|
*/
|
||||||
|
default SlotBuilder setCaptiveFilter(@NotNull final CaptiveFilter filter) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the ItemStack updater.
|
* Set the ItemStack updater.
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.willfp.eco.core.gui.slot.functional;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.gui.menu.Menu;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface to test if a captive slot is allowed to contain an item given a player and a menu.
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface CaptiveFilter {
|
||||||
|
/**
|
||||||
|
* Get if allowed.
|
||||||
|
*
|
||||||
|
* @param player The player.
|
||||||
|
* @param menu The menu.
|
||||||
|
* @param itemStack The item.
|
||||||
|
* @return If captive.
|
||||||
|
*/
|
||||||
|
boolean isAllowed(@NotNull Player player,
|
||||||
|
@NotNull Menu menu,
|
||||||
|
@Nullable ItemStack itemStack);
|
||||||
|
}
|
||||||
@@ -33,10 +33,15 @@ public final class McmmoManager {
|
|||||||
* @return The bonus drop count.
|
* @return The bonus drop count.
|
||||||
*/
|
*/
|
||||||
public static int getBonusDropCount(@NotNull final Block block) {
|
public static int getBonusDropCount(@NotNull final Block block) {
|
||||||
|
int finalValue = 0;
|
||||||
for (McmmoIntegration mcmmoIntegration : REGISTERED) {
|
for (McmmoIntegration mcmmoIntegration : REGISTERED) {
|
||||||
return mcmmoIntegration.getBonusDropCount(block);
|
finalValue += mcmmoIntegration.getBonusDropCount(block);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return 0;
|
return finalValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -47,7 +52,10 @@ public final class McmmoManager {
|
|||||||
*/
|
*/
|
||||||
public static boolean isFake(@NotNull final Event event) {
|
public static boolean isFake(@NotNull final Event event) {
|
||||||
for (McmmoIntegration mcmmoIntegration : REGISTERED) {
|
for (McmmoIntegration mcmmoIntegration : REGISTERED) {
|
||||||
return mcmmoIntegration.isFake(event);
|
if (mcmmoIntegration.isFake(event)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package com.willfp.eco.core.integrations.shop;
|
package com.willfp.eco.core.integrations.shop;
|
||||||
|
|
||||||
import com.willfp.eco.core.integrations.Integration;
|
import com.willfp.eco.core.integrations.Integration;
|
||||||
|
import com.willfp.eco.core.price.Price;
|
||||||
|
import com.willfp.eco.core.price.impl.PriceFree;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
@@ -29,12 +31,41 @@ public interface ShopIntegration extends Integration {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if an item is sellable for a player.
|
||||||
|
*
|
||||||
|
* @param itemStack The item.
|
||||||
|
* @param player The player.
|
||||||
|
* @return If sellable.
|
||||||
|
*/
|
||||||
|
default boolean isSellable(@NotNull final ItemStack itemStack,
|
||||||
|
@NotNull final Player player) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of one of an item for a player.
|
||||||
|
* <p>
|
||||||
|
* For example, if you pass in a stack, it will only return the value of <b>one</b> item, not the full stack.
|
||||||
|
*
|
||||||
|
* @param itemStack The item.
|
||||||
|
* @param player The player.
|
||||||
|
* @return The price.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
default Price getUnitValue(@NotNull final ItemStack itemStack,
|
||||||
|
@NotNull final Player player) {
|
||||||
|
return new PriceFree();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the price of an item.
|
* Get the price of an item.
|
||||||
*
|
*
|
||||||
* @param itemStack The item.
|
* @param itemStack The item.
|
||||||
* @return The price.
|
* @return The price.
|
||||||
|
* @deprecated Use getValue instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(since = "6.47.0", forRemoval = true)
|
||||||
default double getPrice(@NotNull final ItemStack itemStack) {
|
default double getPrice(@NotNull final ItemStack itemStack) {
|
||||||
// Do nothing unless overridden.
|
// Do nothing unless overridden.
|
||||||
return 0.0;
|
return 0.0;
|
||||||
@@ -46,9 +77,11 @@ public interface ShopIntegration extends Integration {
|
|||||||
* @param itemStack The item.
|
* @param itemStack The item.
|
||||||
* @param player The player.
|
* @param player The player.
|
||||||
* @return The price.
|
* @return The price.
|
||||||
|
* @deprecated Use getValue instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(since = "6.47.0", forRemoval = true)
|
||||||
default double getPrice(@NotNull final ItemStack itemStack,
|
default double getPrice(@NotNull final ItemStack itemStack,
|
||||||
@NotNull final Player player) {
|
@NotNull final Player player) {
|
||||||
return getPrice(itemStack);
|
return getUnitValue(itemStack, player).getValue(player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.willfp.eco.core.integrations.shop;
|
package com.willfp.eco.core.integrations.shop;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.price.Price;
|
||||||
|
import com.willfp.eco.core.price.impl.PriceFree;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -36,12 +38,57 @@ public final class ShopManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if an item is sellable for a player.
|
||||||
|
*
|
||||||
|
* @param itemStack The item.
|
||||||
|
* @param player The player.
|
||||||
|
* @return If sellable.
|
||||||
|
*/
|
||||||
|
public static boolean isSellable(@Nullable final ItemStack itemStack,
|
||||||
|
@NotNull final Player player) {
|
||||||
|
if (itemStack == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ShopIntegration integration : REGISTERED) {
|
||||||
|
return integration.isSellable(itemStack, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of one of an item for a player.
|
||||||
|
* <p>
|
||||||
|
* For example, if you pass in a stack, it will only return the value of <b>one</b> item, not the full stack.
|
||||||
|
*
|
||||||
|
* @param itemStack The item.
|
||||||
|
* @param player The player.
|
||||||
|
* @return The price.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static Price getUnitValue(@Nullable final ItemStack itemStack,
|
||||||
|
@NotNull final Player player) {
|
||||||
|
if (itemStack == null) {
|
||||||
|
return new PriceFree();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ShopIntegration integration : REGISTERED) {
|
||||||
|
return integration.getUnitValue(itemStack, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new PriceFree();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the price of an item.
|
* Get the price of an item.
|
||||||
*
|
*
|
||||||
* @param itemStack The item.
|
* @param itemStack The item.
|
||||||
* @return The price.
|
* @return The price.
|
||||||
|
* @deprecated Use getValue instead. This will always return 0 as prices depend on players.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(since = "6.47.0", forRemoval = true)
|
||||||
public static double getItemPrice(@Nullable final ItemStack itemStack) {
|
public static double getItemPrice(@Nullable final ItemStack itemStack) {
|
||||||
return getItemPrice(itemStack, null);
|
return getItemPrice(itemStack, null);
|
||||||
}
|
}
|
||||||
@@ -52,19 +99,17 @@ public final class ShopManager {
|
|||||||
* @param itemStack The item.
|
* @param itemStack The item.
|
||||||
* @param player The player.
|
* @param player The player.
|
||||||
* @return The price.
|
* @return The price.
|
||||||
|
* @deprecated Use getValue instead. Null players / null items will always return 0.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(since = "6.47.0", forRemoval = true)
|
||||||
public static double getItemPrice(@Nullable final ItemStack itemStack,
|
public static double getItemPrice(@Nullable final ItemStack itemStack,
|
||||||
@Nullable final Player player) {
|
@Nullable final Player player) {
|
||||||
if (itemStack == null) {
|
if (itemStack == null || player == null) {
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ShopIntegration shopIntegration : REGISTERED) {
|
for (ShopIntegration shopIntegration : REGISTERED) {
|
||||||
if (player == null) {
|
return shopIntegration.getUnitValue(itemStack, player).getValue(player, itemStack.getAmount());
|
||||||
return shopIntegration.getPrice(itemStack);
|
|
||||||
} else {
|
|
||||||
return shopIntegration.getPrice(itemStack, player);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0.0;
|
return 0.0;
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.willfp.eco.core.integrations.shop;
|
package com.willfp.eco.core.integrations.shop;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.price.Price;
|
||||||
|
import com.willfp.eco.core.price.impl.PriceEconomy;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
import org.bukkit.event.player.PlayerEvent;
|
import org.bukkit.event.player.PlayerEvent;
|
||||||
@@ -19,7 +21,12 @@ public class ShopSellEvent extends PlayerEvent {
|
|||||||
/**
|
/**
|
||||||
* The sell price.
|
* The sell price.
|
||||||
*/
|
*/
|
||||||
private double price;
|
private Price price;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The price multiplier.
|
||||||
|
*/
|
||||||
|
private double multiplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The item to be sold.
|
* The item to be sold.
|
||||||
@@ -33,31 +40,64 @@ public class ShopSellEvent extends PlayerEvent {
|
|||||||
* @param who The player.
|
* @param who The player.
|
||||||
* @param price The price.
|
* @param price The price.
|
||||||
* @param item The item.
|
* @param item The item.
|
||||||
|
* @deprecated Use the price system instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(since = "6.47.0", forRemoval = true)
|
||||||
public ShopSellEvent(@NotNull final Player who,
|
public ShopSellEvent(@NotNull final Player who,
|
||||||
final double price,
|
final double price,
|
||||||
@Nullable final ItemStack item) {
|
@Nullable final ItemStack item) {
|
||||||
|
this(who, new PriceEconomy(price), item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new shop sell event.
|
||||||
|
*
|
||||||
|
* @param who The player.
|
||||||
|
* @param price The price.
|
||||||
|
* @param item The item.
|
||||||
|
*/
|
||||||
|
public ShopSellEvent(@NotNull final Player who,
|
||||||
|
@NotNull final Price price,
|
||||||
|
@Nullable final ItemStack item) {
|
||||||
|
this(who, price, item, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new shop sell event.
|
||||||
|
*
|
||||||
|
* @param who The player.
|
||||||
|
* @param price The price.
|
||||||
|
* @param item The item.
|
||||||
|
* @param multiplier The multiplier.
|
||||||
|
*/
|
||||||
|
public ShopSellEvent(@NotNull final Player who,
|
||||||
|
@NotNull final Price price,
|
||||||
|
@Nullable final ItemStack item,
|
||||||
|
final double multiplier) {
|
||||||
super(who);
|
super(who);
|
||||||
|
|
||||||
this.price = price;
|
this.price = price;
|
||||||
this.item = item;
|
this.item = item;
|
||||||
|
|
||||||
|
this.multiplier = multiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the price.
|
* Get the value.
|
||||||
*
|
*
|
||||||
* @return The price.
|
* @return The value.
|
||||||
*/
|
*/
|
||||||
public double getPrice() {
|
@NotNull
|
||||||
|
public Price getValue() {
|
||||||
return this.price;
|
return this.price;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the price.
|
* Set the value.
|
||||||
*
|
*
|
||||||
* @param price The price.
|
* @param price The value.
|
||||||
*/
|
*/
|
||||||
public void setPrice(final double price) {
|
public void setValue(@NotNull final Price price) {
|
||||||
this.price = price;
|
this.price = price;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,6 +121,46 @@ public class ShopSellEvent extends PlayerEvent {
|
|||||||
return item != null;
|
return item != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the price multiplier.
|
||||||
|
*
|
||||||
|
* @return The multiplier.
|
||||||
|
*/
|
||||||
|
public double getMultiplier() {
|
||||||
|
return multiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the price multiplier.
|
||||||
|
*
|
||||||
|
* @param multiplier The multiplier.
|
||||||
|
*/
|
||||||
|
public void setMultiplier(final double multiplier) {
|
||||||
|
this.multiplier = multiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the price.
|
||||||
|
*
|
||||||
|
* @return The price.
|
||||||
|
* @deprecated Use the price system instead.
|
||||||
|
*/
|
||||||
|
@Deprecated(since = "6.47.0", forRemoval = true)
|
||||||
|
public double getPrice() {
|
||||||
|
return this.getValue().getValue(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the price.
|
||||||
|
*
|
||||||
|
* @param price The price.
|
||||||
|
* @deprecated Use the price system instead.
|
||||||
|
*/
|
||||||
|
@Deprecated(since = "6.47.0", forRemoval = true)
|
||||||
|
public void setPrice(final double price) {
|
||||||
|
this.setValue(new PriceEconomy(price));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bukkit parity.
|
* Bukkit parity.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ public abstract class AbstractItemStackBuilder<T extends ItemMeta, U extends Abs
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public U setAmount(final int amount) {
|
public U setAmount(final int amount) {
|
||||||
Validate.isTrue(amount >= 1 && amount <= base.getMaxStackSize());
|
Validate.isTrue(amount >= 1);
|
||||||
base.setAmount(amount);
|
base.setAmount(amount);
|
||||||
return (U) this;
|
return (U) this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,156 @@
|
|||||||
|
package com.willfp.eco.core.price;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A group of {@link ConfiguredPrice}s in order to show them
|
||||||
|
* to players in one go.
|
||||||
|
*/
|
||||||
|
public final class CombinedDisplayPrice {
|
||||||
|
/**
|
||||||
|
* Maps configured prices to multipliers.
|
||||||
|
*/
|
||||||
|
private final Map<ConfiguredPrice, Double> prices;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The player to format for.
|
||||||
|
*/
|
||||||
|
private final Player player;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a new combined price mapping formatters to multipliers.
|
||||||
|
*
|
||||||
|
* @param player The player.
|
||||||
|
* @param prices The prices.
|
||||||
|
*/
|
||||||
|
private CombinedDisplayPrice(@NotNull final Player player,
|
||||||
|
@NotNull final Map<ConfiguredPrice, Double> prices) {
|
||||||
|
this.player = player;
|
||||||
|
this.prices = prices;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the display strings.
|
||||||
|
*
|
||||||
|
* @return The display strings.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public String[] getDisplayStrings() {
|
||||||
|
List<String> displayStrings = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Map.Entry<ConfiguredPrice, Double> entry : prices.entrySet()) {
|
||||||
|
displayStrings.add(entry.getKey().getDisplay(player, entry.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return displayStrings.toArray(new String[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The builder.
|
||||||
|
*/
|
||||||
|
public static class Builder {
|
||||||
|
/**
|
||||||
|
* All multiplied prices.
|
||||||
|
*/
|
||||||
|
private final List<MultipliedPrice> prices = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The player.
|
||||||
|
*/
|
||||||
|
private final Player player;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new builder.
|
||||||
|
*
|
||||||
|
* @param player The player.
|
||||||
|
*/
|
||||||
|
Builder(@NotNull final Player player) {
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new price with a certain multiplier.
|
||||||
|
*
|
||||||
|
* @param price The price.
|
||||||
|
* @param multiplier The multiplier.
|
||||||
|
* @return The builder.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public Builder add(@NotNull final ConfiguredPrice price,
|
||||||
|
final double multiplier) {
|
||||||
|
prices.add(new MultipliedPrice(price, multiplier));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new price.
|
||||||
|
*
|
||||||
|
* @param price The price.
|
||||||
|
* @return The builder.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public Builder add(@NotNull final ConfiguredPrice price) {
|
||||||
|
return this.add(price, 1D);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build into a {@link CombinedDisplayPrice}.
|
||||||
|
*
|
||||||
|
* @return The combined price.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public CombinedDisplayPrice build() {
|
||||||
|
Map<ConfiguredPrice, Double> unitPrices = new HashMap<>();
|
||||||
|
|
||||||
|
// Take first configured price at each ID as the format for all prices with that ID.
|
||||||
|
for (MultipliedPrice price : prices) {
|
||||||
|
// Find the base price.
|
||||||
|
ConfiguredPrice base = unitPrices.keySet()
|
||||||
|
.stream()
|
||||||
|
.filter(it -> it.getIdentifier().equals(price.price().getIdentifier()))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(price.price());
|
||||||
|
|
||||||
|
// Find the multiplier for a value of 1, e.g. a price that's worth 20 will be 0.05.
|
||||||
|
double unitMultiplier = 1 / base.getValue(player);
|
||||||
|
|
||||||
|
double currentMultiplier = unitPrices.getOrDefault(base, 0D);
|
||||||
|
currentMultiplier += unitMultiplier * price.price().getValue(player, price.multiplier());
|
||||||
|
unitPrices.put(base, currentMultiplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new CombinedDisplayPrice(player, unitPrices);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A price with a multiplier.
|
||||||
|
*
|
||||||
|
* @param price The price.
|
||||||
|
* @param multiplier The multiplier.
|
||||||
|
*/
|
||||||
|
private record MultipliedPrice(
|
||||||
|
@NotNull ConfiguredPrice price,
|
||||||
|
double multiplier
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new builder for a player.
|
||||||
|
*
|
||||||
|
* @param player The player.
|
||||||
|
* @return The builder.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static Builder builder(@NotNull final Player player) {
|
||||||
|
return new Builder(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,7 +24,7 @@ public final class ConfiguredPrice implements Price {
|
|||||||
/**
|
/**
|
||||||
* Free.
|
* Free.
|
||||||
*/
|
*/
|
||||||
private static final ConfiguredPrice FREE = new ConfiguredPrice(
|
public static final ConfiguredPrice FREE = new ConfiguredPrice(
|
||||||
new PriceFree(),
|
new PriceFree(),
|
||||||
"Free"
|
"Free"
|
||||||
);
|
);
|
||||||
@@ -52,23 +52,27 @@ public final class ConfiguredPrice implements Price {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canAfford(@NotNull final Player player) {
|
public boolean canAfford(@NotNull final Player player,
|
||||||
return this.price.canAfford(player);
|
final double multiplier) {
|
||||||
|
return this.price.canAfford(player, multiplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void pay(@NotNull final Player player) {
|
public void pay(@NotNull final Player player,
|
||||||
this.price.pay(player);
|
final double multiplier) {
|
||||||
|
this.price.pay(player, multiplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void giveTo(@NotNull final Player player) {
|
public void giveTo(@NotNull final Player player,
|
||||||
this.price.giveTo(player);
|
final double multiplier) {
|
||||||
|
this.price.giveTo(player, multiplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getValue(@NotNull final Player player) {
|
public double getValue(@NotNull final Player player,
|
||||||
return this.price.getValue(player);
|
final double multiplier) {
|
||||||
|
return this.price.getValue(player, multiplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -82,6 +86,11 @@ public final class ConfiguredPrice implements Price {
|
|||||||
this.price.setMultiplier(player, multiplier);
|
this.price.setMultiplier(player, multiplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getIdentifier() {
|
||||||
|
return this.price.getIdentifier();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the price that this delegates to.
|
* Get the price that this delegates to.
|
||||||
*
|
*
|
||||||
@@ -98,8 +107,20 @@ public final class ConfiguredPrice implements Price {
|
|||||||
* @return The display string.
|
* @return The display string.
|
||||||
*/
|
*/
|
||||||
public String getDisplay(@NotNull final Player player) {
|
public String getDisplay(@NotNull final Player player) {
|
||||||
|
return this.getDisplay(player, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the display string for a player.
|
||||||
|
*
|
||||||
|
* @param player The player.
|
||||||
|
* @param multiplier The multiplier.
|
||||||
|
* @return The display string.
|
||||||
|
*/
|
||||||
|
public String getDisplay(@NotNull final Player player,
|
||||||
|
final double multiplier) {
|
||||||
return StringUtils.format(
|
return StringUtils.format(
|
||||||
formatString.replace("%value%", NumberUtils.format(this.getPrice().getValue(player))),
|
formatString.replace("%value%", NumberUtils.format(this.getPrice().getValue(player, multiplier))),
|
||||||
player,
|
player,
|
||||||
StringUtils.FormatOption.WITH_PLACEHOLDERS
|
StringUtils.FormatOption.WITH_PLACEHOLDERS
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,49 +1,150 @@
|
|||||||
package com.willfp.eco.core.price;
|
package com.willfp.eco.core.price;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.NotImplementedException;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A price that a player should pay.
|
* A price that a player should pay.
|
||||||
|
* <p>
|
||||||
|
* There are important implementation details:
|
||||||
|
* <p>
|
||||||
|
* For backwards compatibility, all methods are default, however you must override the following:
|
||||||
|
* <ul>
|
||||||
|
* <li><code>canAfford(Player, double)</code></li>
|
||||||
|
* <li><code>pay(Player, double)</code></li>
|
||||||
|
* <li><code>giveTo(Player, double)</code></li>
|
||||||
|
* <li><code>getValue(Player, double)</code></li>
|
||||||
|
* <li><code>getMultiplier(Player)</code></li>
|
||||||
|
* <li><code>setMultiplier(Player, double)</code></li>
|
||||||
|
* </ul>
|
||||||
|
* Otherwise, your implementation will throw {@link NotImplementedException}.
|
||||||
|
* <p>
|
||||||
|
* Also, getValue() should always return the value with player multipliers applied.
|
||||||
*/
|
*/
|
||||||
public interface Price {
|
public interface Price {
|
||||||
/**
|
/**
|
||||||
* Get if the player can afford the price.
|
* Get if a player can afford to pay the price.
|
||||||
*
|
*
|
||||||
* @param player The player.
|
* @param player The player.
|
||||||
* @return If the player can afford.
|
* @return If the player can afford.
|
||||||
*/
|
*/
|
||||||
boolean canAfford(@NotNull Player player);
|
default boolean canAfford(@NotNull final Player player) {
|
||||||
|
return this.canAfford(player, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if a player can afford to pay x times the price.
|
||||||
|
*
|
||||||
|
* @param player The player.
|
||||||
|
* @param multiplier The multiplier.
|
||||||
|
* @return If the player can afford.
|
||||||
|
*/
|
||||||
|
default boolean canAfford(@NotNull final Player player,
|
||||||
|
final double multiplier) {
|
||||||
|
throw new NotImplementedException("Override canAfford(Player, double) in your Price implementation!");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make the player pay the price.
|
* Make the player pay the price.
|
||||||
* <p>
|
* <p>
|
||||||
* Only run this if the player can afford the price.
|
* Check canAfford first.
|
||||||
*
|
*
|
||||||
* @param player The player.
|
* @param player The player.
|
||||||
*/
|
*/
|
||||||
void pay(@NotNull Player player);
|
default void pay(@NotNull final Player player) {
|
||||||
|
this.pay(player, 1);
|
||||||
/**
|
|
||||||
* Give the value of the price to the player.
|
|
||||||
* <p>
|
|
||||||
* You should override this method, it's only marked as default for
|
|
||||||
* backwards compatibility purposes.
|
|
||||||
*
|
|
||||||
* @param player The player.
|
|
||||||
*/
|
|
||||||
default void giveTo(@NotNull Player player) {
|
|
||||||
// Override when needed.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the price is backed by a value, get it here.
|
* Make the player pay the price x times.
|
||||||
|
* <p>
|
||||||
|
* Check canAfford first.
|
||||||
|
*
|
||||||
|
* @param player The player.
|
||||||
|
* @param multiplier The multiplier.
|
||||||
|
*/
|
||||||
|
default void pay(@NotNull final Player player,
|
||||||
|
final double multiplier) {
|
||||||
|
throw new NotImplementedException("Override pay(Player, double) in your Price implementation!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Give the price to the player.
|
||||||
|
*
|
||||||
|
* @param player The player.
|
||||||
|
*/
|
||||||
|
default void giveTo(@NotNull final Player player) {
|
||||||
|
this.giveTo(player, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Give the price to the player x times.
|
||||||
|
*
|
||||||
|
* @param player The player.
|
||||||
|
* @param multiplier The multiplier.
|
||||||
|
*/
|
||||||
|
default void giveTo(@NotNull final Player player,
|
||||||
|
final double multiplier) {
|
||||||
|
throw new NotImplementedException("Override giveTo(Player, double) in your Price implementation!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the numerical value that backs this price.
|
||||||
*
|
*
|
||||||
* @param player The player.
|
* @param player The player.
|
||||||
* @return The value.
|
* @return The value.
|
||||||
*/
|
*/
|
||||||
default double getValue(@NotNull final Player player) {
|
default double getValue(@NotNull final Player player) {
|
||||||
return 0;
|
return getValue(player, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the numeral value that backs this price multiplied x times.
|
||||||
|
*
|
||||||
|
* @param player The player.
|
||||||
|
* @param multiplier The multiplier.
|
||||||
|
* @return The value.
|
||||||
|
*/
|
||||||
|
default double getValue(@NotNull final Player player,
|
||||||
|
final double multiplier) {
|
||||||
|
throw new NotImplementedException("Override getValue(Player, double) in your Price implementation!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value multiplier for the player.
|
||||||
|
*
|
||||||
|
* @param player The player.
|
||||||
|
* @return The multiplier.
|
||||||
|
*/
|
||||||
|
default double getMultiplier(@NotNull final Player player) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value multiplier for the player.
|
||||||
|
*
|
||||||
|
* @param player The player.
|
||||||
|
* @param multiplier The multiplier.
|
||||||
|
*/
|
||||||
|
default void setMultiplier(@NotNull final Player player,
|
||||||
|
final double multiplier) {
|
||||||
|
throw new NotImplementedException("Override setMultiplier(Player, double) in your Price implementation!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the identifier of this price (as type/instance checks break with delegation,
|
||||||
|
* this is used for combining prices, etc.)
|
||||||
|
* <p>
|
||||||
|
* By default, this uses the class name, but it's good practice to override this.
|
||||||
|
* <p>
|
||||||
|
* It's also good practice to prefix your identifiers with some kind of namespace or
|
||||||
|
* internal ID, in order to prevent conflicts.
|
||||||
|
*
|
||||||
|
* @return The identifier.
|
||||||
|
*/
|
||||||
|
default String getIdentifier() {
|
||||||
|
return this.getClass().getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -61,31 +162,10 @@ public interface Price {
|
|||||||
* If the price is backed by a value, set it here.
|
* If the price is backed by a value, set it here.
|
||||||
*
|
*
|
||||||
* @param value The value.
|
* @param value The value.
|
||||||
* @deprecated Values shouldn't be fixed.
|
* @deprecated Values shouldn't be fixed. This method should never work.
|
||||||
*/
|
*/
|
||||||
@Deprecated(since = "6.45.0", forRemoval = true)
|
@Deprecated(since = "6.45.0", forRemoval = true)
|
||||||
default void setValue(final double value) {
|
default void setValue(final double value) {
|
||||||
// Override when needed.
|
// Override when needed.
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the price multiplier for a player.
|
|
||||||
*
|
|
||||||
* @param player The player.
|
|
||||||
* @return The value.
|
|
||||||
*/
|
|
||||||
default double getMultiplier(@NotNull final Player player) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the price multiplier for a player.
|
|
||||||
*
|
|
||||||
* @param player The player.
|
|
||||||
* @param multiplier The multiplier.
|
|
||||||
*/
|
|
||||||
default void setMultiplier(@NotNull final Player player,
|
|
||||||
final double multiplier) {
|
|
||||||
// Override when needed.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,23 +52,27 @@ public final class PriceEconomy implements Price {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canAfford(@NotNull final Player player) {
|
public boolean canAfford(@NotNull final Player player,
|
||||||
return EconomyManager.getBalance(player) >= getValue(player);
|
final double multiplier) {
|
||||||
|
return EconomyManager.getBalance(player) >= getValue(player, multiplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void pay(@NotNull final Player player) {
|
public void pay(@NotNull final Player player,
|
||||||
EconomyManager.removeMoney(player, getValue(player));
|
final double multiplier) {
|
||||||
|
EconomyManager.removeMoney(player, getValue(player, multiplier));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void giveTo(@NotNull final Player player) {
|
public void giveTo(@NotNull final Player player,
|
||||||
EconomyManager.giveMoney(player, getValue(player));
|
final double multiplier) {
|
||||||
|
EconomyManager.giveMoney(player, getValue(player, multiplier));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getValue(@NotNull final Player player) {
|
public double getValue(@NotNull final Player player,
|
||||||
return this.function.apply(MathContext.copyWithPlayer(baseContext, player)) * getMultiplier(player);
|
final double multiplier) {
|
||||||
|
return this.function.apply(MathContext.copyWithPlayer(baseContext, player)) * getMultiplier(player) * multiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -81,4 +85,9 @@ public final class PriceEconomy implements Price {
|
|||||||
final double multiplier) {
|
final double multiplier) {
|
||||||
this.multipliers.put(player.getUniqueId(), multiplier);
|
this.multipliers.put(player.getUniqueId(), multiplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getIdentifier() {
|
||||||
|
return "eco:economy";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,42 @@ public final class PriceFree implements Price {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canAfford(@NotNull final Player player) {
|
public boolean canAfford(@NotNull final Player player,
|
||||||
|
final double multiplier) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void pay(@NotNull final Player player) {
|
public void pay(@NotNull final Player player,
|
||||||
// Do nothing.
|
final double multiplier) {
|
||||||
|
// Nothing.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void giveTo(@NotNull final Player player,
|
||||||
|
final double multiplier) {
|
||||||
|
// Nothing.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getMultiplier(@NotNull final Player player) {
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMultiplier(@NotNull final Player player,
|
||||||
|
final double multiplier) {
|
||||||
|
// Nothing.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getValue(@NotNull final Player player,
|
||||||
|
final double multiplier) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getIdentifier() {
|
||||||
|
return "eco:free";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.willfp.eco.core.price.impl;
|
package com.willfp.eco.core.price.impl;
|
||||||
|
|
||||||
import com.willfp.eco.core.drops.DropQueue;
|
import com.willfp.eco.core.drops.DropQueue;
|
||||||
|
import com.willfp.eco.core.items.HashedItem;
|
||||||
import com.willfp.eco.core.items.TestableItem;
|
import com.willfp.eco.core.items.TestableItem;
|
||||||
import com.willfp.eco.core.math.MathContext;
|
import com.willfp.eco.core.math.MathContext;
|
||||||
import com.willfp.eco.core.price.Price;
|
import com.willfp.eco.core.price.Price;
|
||||||
@@ -74,8 +75,9 @@ public final class PriceItem implements Price {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canAfford(@NotNull final Player player) {
|
public boolean canAfford(@NotNull final Player player,
|
||||||
int toRemove = (int) getValue(player);
|
final double multiplier) {
|
||||||
|
int toRemove = (int) getValue(player, multiplier);
|
||||||
if (toRemove <= 0) {
|
if (toRemove <= 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -92,8 +94,9 @@ public final class PriceItem implements Price {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void pay(@NotNull final Player player) {
|
public void pay(@NotNull final Player player,
|
||||||
int toRemove = (int) getValue(player);
|
final double multiplier) {
|
||||||
|
int toRemove = (int) getValue(player, multiplier);
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
for (ItemStack itemStack : player.getInventory().getContents()) {
|
for (ItemStack itemStack : player.getInventory().getContents()) {
|
||||||
@@ -119,9 +122,10 @@ public final class PriceItem implements Price {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void giveTo(@NotNull final Player player) {
|
public void giveTo(@NotNull final Player player,
|
||||||
|
final double multiplier) {
|
||||||
ItemStack itemStack = item.getItem().clone();
|
ItemStack itemStack = item.getItem().clone();
|
||||||
itemStack.setAmount((int) getValue(player));
|
itemStack.setAmount((int) getValue(player, multiplier));
|
||||||
|
|
||||||
new DropQueue(player)
|
new DropQueue(player)
|
||||||
.addItem(itemStack)
|
.addItem(itemStack)
|
||||||
@@ -130,9 +134,11 @@ public final class PriceItem implements Price {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getValue(@NotNull final Player player) {
|
public double getValue(@NotNull final Player player,
|
||||||
|
final double multiplier) {
|
||||||
return Math.toIntExact(Math.round(
|
return Math.toIntExact(Math.round(
|
||||||
this.function.apply(MathContext.copyWithPlayer(baseContext, player)) * getMultiplier(player)
|
this.function.apply(MathContext.copyWithPlayer(baseContext, player))
|
||||||
|
* getMultiplier(player) * multiplier
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,4 +152,9 @@ public final class PriceItem implements Price {
|
|||||||
final double multiplier) {
|
final double multiplier) {
|
||||||
this.multipliers.put(player.getUniqueId(), multiplier);
|
this.multipliers.put(player.getUniqueId(), multiplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getIdentifier() {
|
||||||
|
return "eco:item-" + HashedItem.of(this.item.getItem()).getHash();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ public final class ProxyConstants {
|
|||||||
"v1_17_R1",
|
"v1_17_R1",
|
||||||
"v1_18_R1",
|
"v1_18_R1",
|
||||||
"v1_18_R2",
|
"v1_18_R2",
|
||||||
"v1_19_R1"
|
"v1_19_R1",
|
||||||
|
"v1_19_R2"
|
||||||
);
|
);
|
||||||
|
|
||||||
private ProxyConstants() {
|
private ProxyConstants() {
|
||||||
|
|||||||
@@ -85,8 +85,8 @@ public record PlayableSound(@NotNull Sound sound,
|
|||||||
try {
|
try {
|
||||||
Sound sound = Sound.valueOf(config.getString("sound").toUpperCase());
|
Sound sound = Sound.valueOf(config.getString("sound").toUpperCase());
|
||||||
|
|
||||||
double pitch = Objects.requireNonNullElse(config.getDouble("pitch"), 1.0);
|
double pitch = Objects.requireNonNullElse(config.getDoubleOrNull("pitch"), 1.0);
|
||||||
double volume = Objects.requireNonNullElse(config.getDouble("volume"), 1.0);
|
double volume = Objects.requireNonNullElse(config.getDoubleOrNull("volume"), 1.0);
|
||||||
|
|
||||||
return new PlayableSound(
|
return new PlayableSound(
|
||||||
sound,
|
sound,
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
/**
|
/**
|
||||||
* Utilities / API methods for item durability.
|
* Utilities / API methods for item durability.
|
||||||
*/
|
*/
|
||||||
|
// Have to suppress casts to ItemMeta because the methods don't exist for some older versions that eco supports.
|
||||||
|
@SuppressWarnings("RedundantCast")
|
||||||
public final class DurabilityUtils {
|
public final class DurabilityUtils {
|
||||||
/**
|
/**
|
||||||
* Damage an item in a player's inventory.
|
* Damage an item in a player's inventory.
|
||||||
|
|||||||
@@ -579,7 +579,7 @@ public final class StringUtils {
|
|||||||
*
|
*
|
||||||
* @param lookup The lookup string.
|
* @param lookup The lookup string.
|
||||||
* @return An array of tokens to be processed.
|
* @return An array of tokens to be processed.
|
||||||
* @author Shawn (https://stackoverflow.com/questions/70606170/split-a-list-on-spaces-and-group-quoted-characters/70606653#70606653)
|
* @author Shawn (<a href="https://stackoverflow.com/questions/70606170/split-a-list-on-spaces-and-group-quoted-characters/70606653#70606653">...</a>)
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public static String[] parseTokens(@NotNull final String lookup) {
|
public static String[] parseTokens(@NotNull final String lookup) {
|
||||||
|
|||||||
@@ -4,9 +4,14 @@ package com.willfp.eco.core.commands
|
|||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin
|
import com.willfp.eco.core.EcoPlugin
|
||||||
import com.willfp.eco.core.command.CommandBase
|
import com.willfp.eco.core.command.CommandBase
|
||||||
|
import com.willfp.eco.core.command.NotificationException
|
||||||
import com.willfp.eco.core.command.impl.PluginCommand
|
import com.willfp.eco.core.command.impl.PluginCommand
|
||||||
import com.willfp.eco.core.command.impl.Subcommand
|
import com.willfp.eco.core.command.impl.Subcommand
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.OfflinePlayer
|
||||||
import org.bukkit.command.CommandSender
|
import org.bukkit.command.CommandSender
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import java.util.function.Predicate
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class for creating commands with builders.
|
* Helper class for creating commands with builders.
|
||||||
@@ -140,3 +145,92 @@ fun CommandBase.addSubcommand(
|
|||||||
init(command)
|
init(command)
|
||||||
return command
|
return command
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws an exception containing a langYml key if obj is null.
|
||||||
|
* <p>The {@link CommandBase#onExecute(CommandSender, List) onExecute } in PluginCommand and Subcommand
|
||||||
|
* automatically handles sending the message to the sender.</p>
|
||||||
|
* <br>
|
||||||
|
* @param key key of notification message in langYml
|
||||||
|
* @return Returns the object given or throws an exception
|
||||||
|
* @throws NotificationException exception thrown when null
|
||||||
|
*/
|
||||||
|
fun <T> T.notifyNull(key: String): T {
|
||||||
|
return this ?: throw NotificationException(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws an exception containing a langYml key if predicate tests false
|
||||||
|
* <p>The {@link CommandBase#onExecute(CommandSender, List) onExecute } in PluginCommand and Subcommand
|
||||||
|
* automatically handles sending the message to the sender.</p>
|
||||||
|
* <br>
|
||||||
|
* @param predicate predicate to test
|
||||||
|
* @param key key of notification message in langYml
|
||||||
|
* @param <T> the generic type of object
|
||||||
|
* @return Returns the object given or throws an exception
|
||||||
|
*/
|
||||||
|
fun <T> T.notifyFalse(predicate: Predicate<T>, key: String): T {
|
||||||
|
predicate.test(this).notifyFalse(key)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws an exception containing a langYml key if condition is false.
|
||||||
|
* <p>The {@link CommandBase#onExecute(CommandSender, List) onExecute } in PluginCommand and Subcommand
|
||||||
|
* automatically handles sending the message to the sender.</p>
|
||||||
|
* <br>
|
||||||
|
* @param key value in the langYml
|
||||||
|
* @return Returns the condition given or throws an exception
|
||||||
|
* @throws NotificationException exception thrown when false
|
||||||
|
*/
|
||||||
|
fun Boolean?.notifyFalse(key: String): Boolean {
|
||||||
|
return if (this == true) true else throw NotificationException(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws an exception containing a langYml key if Bukkit.getPlayer(playerName) is null.
|
||||||
|
* <p>The {@link CommandBase#onExecute(CommandSender, List) onExecute } in PluginCommand and Subcommand
|
||||||
|
* automatically handles sending the message to the sender.</p>
|
||||||
|
* <br>
|
||||||
|
* @param key value in the langYml
|
||||||
|
* @return Returns the player
|
||||||
|
* @throws NotificationException exception thrown when invalid playerName
|
||||||
|
*/
|
||||||
|
fun String?.notifyPlayerRequired(key: String): Player {
|
||||||
|
return Bukkit.getPlayer(this ?: "") ?: throw NotificationException(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws an exception containing a langYml key if Bukkit.getPlayer(playerName) is null.
|
||||||
|
* <p>The {@link CommandBase#onExecute(CommandSender, List) onExecute } in PluginCommand and Subcommand
|
||||||
|
* automatically handles sending the message to the sender.</p>
|
||||||
|
* <br>
|
||||||
|
* @param key value in the langYml
|
||||||
|
* @return Returns the player
|
||||||
|
* @throws NotificationException exception thrown when invalid playerName
|
||||||
|
*/
|
||||||
|
fun String?.notifyOfflinePlayerRequired(key: String): OfflinePlayer {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
val player = Bukkit.getOfflinePlayer(this ?: "")
|
||||||
|
|
||||||
|
if (!player.hasPlayedBefore() && !player.isOnline) {
|
||||||
|
throw NotificationException(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
return player
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws an exception containing a langYml key if player doesn't have permission.
|
||||||
|
* <p>The {@link CommandBase#onExecute(CommandSender, List) onExecute } in PluginCommand and Subcommand
|
||||||
|
* automatically handles sending the message to the sender.</p>
|
||||||
|
* <br>
|
||||||
|
* @param permission the permission
|
||||||
|
* @param key value in the langYml
|
||||||
|
* @return Returns the player
|
||||||
|
* @throws NotificationException exception thrown when player doesn't have permission
|
||||||
|
*/
|
||||||
|
fun Player?.notifyPermissionRequired(permission: String, key: String): Player {
|
||||||
|
this ?: throw NotificationException(key)
|
||||||
|
return this.notifyFalse({ this.hasPermission(permission) }, key)
|
||||||
|
}
|
||||||
|
|||||||
@@ -74,12 +74,15 @@ fun SlotBuilder.onClick(clickType: ClickType, action: (Player, InventoryClickEve
|
|||||||
fun SlotBuilder.notCaptiveFor(test: (Player) -> Boolean): SlotBuilder =
|
fun SlotBuilder.notCaptiveFor(test: (Player) -> Boolean): SlotBuilder =
|
||||||
this.notCaptiveFor { test(it) }
|
this.notCaptiveFor { test(it) }
|
||||||
|
|
||||||
|
/** @see SlotBuilder.setCaptiveFilter */
|
||||||
|
fun SlotBuilder.setCaptiveFilter(test: (Player, Menu, ItemStack?) -> Boolean): SlotBuilder =
|
||||||
|
this.setCaptiveFilter { a, b, c -> test(a, b, c) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see SlotBuilder.setModifier
|
* @see SlotBuilder.setModifier
|
||||||
* @deprecated Use SlotUpdater instead.
|
* @deprecated Use SlotUpdater instead.
|
||||||
*/
|
*/
|
||||||
@Deprecated("Use SlotUpdater instead")
|
@Deprecated("Use SlotUpdater instead")
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
fun SlotBuilder.setModifier(action: (Player, Menu, item: ItemStack) -> Unit): SlotBuilder =
|
fun SlotBuilder.setModifier(action: (Player, Menu, item: ItemStack) -> Unit): SlotBuilder =
|
||||||
this.setUpdater { a, b, c -> c.apply { action(a, b, c) } }
|
this.setUpdater { a, b, c -> c.apply { action(a, b, c) } }
|
||||||
|
|
||||||
|
|||||||
@@ -2,13 +2,31 @@
|
|||||||
|
|
||||||
package com.willfp.eco.core.integrations.shop
|
package com.willfp.eco.core.integrations.shop
|
||||||
|
|
||||||
|
import com.willfp.eco.core.price.Price
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
import org.bukkit.inventory.ItemStack
|
import org.bukkit.inventory.ItemStack
|
||||||
|
|
||||||
/** @see ShopManager.getItemPrice * */
|
/** @see ShopManager.getItemPrice * */
|
||||||
|
@Deprecated(
|
||||||
|
"Prices depend on players, this will always return 0.",
|
||||||
|
level = DeprecationLevel.ERROR,
|
||||||
|
replaceWith = ReplaceWith("this.getValue(player)")
|
||||||
|
)
|
||||||
val ItemStack.price: Double
|
val ItemStack.price: Double
|
||||||
get() = ShopManager.getItemPrice(this)
|
get() = 0.0
|
||||||
|
|
||||||
/** @see ShopManager.getItemPrice * */
|
/** @see ShopManager.getItemPrice * */
|
||||||
|
@Deprecated(
|
||||||
|
"Use the price system instead, prices may not be currencies.",
|
||||||
|
ReplaceWith("this.getValue(player)"),
|
||||||
|
)
|
||||||
fun ItemStack.getPrice(player: Player): Double =
|
fun ItemStack.getPrice(player: Player): Double =
|
||||||
ShopManager.getItemPrice(this, player)
|
this.getUnitValue(player).getValue(player, this.amount.toDouble())
|
||||||
|
|
||||||
|
/** @see ShopManager.getUnitValue */
|
||||||
|
fun ItemStack.getUnitValue(player: Player): Price =
|
||||||
|
ShopManager.getUnitValue(this, player)
|
||||||
|
|
||||||
|
/** @see ShopManager.isSellable */
|
||||||
|
fun ItemStack?.isSellable(player: Player): Boolean =
|
||||||
|
ShopManager.isSellable(this, player)
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.willfp.eco.internal.command
|
||||||
|
|
||||||
|
import org.bukkit.command.Command
|
||||||
|
import org.bukkit.command.CommandSender
|
||||||
|
import org.bukkit.command.PluginIdentifiableCommand
|
||||||
|
import org.bukkit.command.TabCompleter
|
||||||
|
|
||||||
|
class DelegatedBukkitCommand(
|
||||||
|
private val delegate: EcoPluginCommand
|
||||||
|
) : Command(delegate.name), TabCompleter, PluginIdentifiableCommand {
|
||||||
|
override fun execute(sender: CommandSender, label: String, args: Array<out String>?): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTabComplete(
|
||||||
|
sender: CommandSender,
|
||||||
|
command: Command,
|
||||||
|
label: String,
|
||||||
|
args: Array<out String>?
|
||||||
|
): List<String> {
|
||||||
|
return mutableListOf() // Mutable in case bukkit requires this (I haven't checked.)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPlugin() = delegate.plugin
|
||||||
|
override fun getPermission() = delegate.permission
|
||||||
|
override fun getDescription() = delegate.description ?: ""
|
||||||
|
override fun getAliases(): List<String> = delegate.aliases
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package com.willfp.eco.internal.command
|
||||||
|
|
||||||
|
import com.willfp.eco.core.Eco
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.command.CommandBase
|
||||||
|
import com.willfp.eco.core.command.PluginCommandBase
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
|
||||||
|
class EcoPluginCommand(
|
||||||
|
parentDelegate: CommandBase,
|
||||||
|
plugin: EcoPlugin,
|
||||||
|
name: String,
|
||||||
|
permission: String,
|
||||||
|
playersOnly: Boolean
|
||||||
|
) : HandledCommand(parentDelegate, plugin, name, permission, playersOnly),
|
||||||
|
PluginCommandBase {
|
||||||
|
override fun register() {
|
||||||
|
val command = Bukkit.getPluginCommand(name)
|
||||||
|
|
||||||
|
if (command == null) {
|
||||||
|
unregister()
|
||||||
|
|
||||||
|
commandMap.register(plugin.name.lowercase(), DelegatedBukkitCommand(this))
|
||||||
|
} else {
|
||||||
|
command.setExecutor(this)
|
||||||
|
|
||||||
|
|
||||||
|
description?.let {
|
||||||
|
command.setDescription(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aliases.isNotEmpty()) {
|
||||||
|
command.aliases = aliases
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun unregister() {
|
||||||
|
val found = commandMap.getCommand(name)
|
||||||
|
found?.unregister(commandMap)
|
||||||
|
|
||||||
|
Eco.get().syncCommands()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EcoSubcommand(
|
||||||
|
parentDelegate: CommandBase,
|
||||||
|
plugin: EcoPlugin,
|
||||||
|
name: String,
|
||||||
|
permission: String,
|
||||||
|
playersOnly: Boolean
|
||||||
|
) : HandledCommand(parentDelegate, plugin, name, permission, playersOnly)
|
||||||
@@ -0,0 +1,183 @@
|
|||||||
|
package com.willfp.eco.internal.command
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.command.CommandBase
|
||||||
|
import com.willfp.eco.core.command.NotificationException
|
||||||
|
import com.willfp.eco.core.config.base.LangYml
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.command.Command
|
||||||
|
import org.bukkit.command.CommandExecutor
|
||||||
|
import org.bukkit.command.CommandMap
|
||||||
|
import org.bukkit.command.CommandSender
|
||||||
|
import org.bukkit.command.TabCompleter
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.util.StringUtil
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract class for commands that can be handled.
|
||||||
|
* <p>
|
||||||
|
* Handled commands have a method to pass in raw input from bukkit commands
|
||||||
|
* in order to execute the command-specific code.
|
||||||
|
*/
|
||||||
|
abstract class HandledCommand(
|
||||||
|
private val parentDelegate: CommandBase,
|
||||||
|
private val plugin: EcoPlugin,
|
||||||
|
private val name: String,
|
||||||
|
private val permission: String,
|
||||||
|
private val playersOnly: Boolean
|
||||||
|
) : CommandBase, CommandExecutor, TabCompleter {
|
||||||
|
private val subcommands = mutableListOf<CommandBase>()
|
||||||
|
|
||||||
|
override fun onCommand(
|
||||||
|
sender: CommandSender,
|
||||||
|
command: Command,
|
||||||
|
label: String,
|
||||||
|
args: Array<out String>?
|
||||||
|
): Boolean {
|
||||||
|
if (!command.name.equals(name, true)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args != null) {
|
||||||
|
handleExecution(sender, args.toList())
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTabComplete(
|
||||||
|
sender: CommandSender,
|
||||||
|
command: Command,
|
||||||
|
label: String,
|
||||||
|
args: Array<out String>?
|
||||||
|
): MutableList<String>? {
|
||||||
|
return handleTabComplete(sender, args?.toList() ?: listOf()).toMutableList()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPlugin() = this.plugin
|
||||||
|
|
||||||
|
override fun getName() = this.name
|
||||||
|
|
||||||
|
override fun getPermission() = this.permission
|
||||||
|
|
||||||
|
override fun isPlayersOnly() = this.playersOnly
|
||||||
|
|
||||||
|
override fun getSubcommands() = this.subcommands
|
||||||
|
|
||||||
|
override fun getWrapped() = this.parentDelegate
|
||||||
|
|
||||||
|
override fun addSubcommand(command: CommandBase): CommandBase {
|
||||||
|
subcommands.add(command)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onExecute(sender: CommandSender, args: List<String>) = parentDelegate.onExecute(sender, args)
|
||||||
|
|
||||||
|
override fun onExecute(sender: Player, args: List<String>) = parentDelegate.onExecute(sender, args)
|
||||||
|
|
||||||
|
override fun tabComplete(sender: CommandSender, args: List<String>): List<String> =
|
||||||
|
parentDelegate.tabComplete(sender, args)
|
||||||
|
|
||||||
|
override fun tabComplete(sender: Player, args: List<String>): List<String> =
|
||||||
|
parentDelegate.tabComplete(sender, args)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the command.
|
||||||
|
*
|
||||||
|
* @param sender The sender.
|
||||||
|
* @param args The arguments.
|
||||||
|
*/
|
||||||
|
private fun CommandBase.handleExecution(sender: CommandSender, args: List<String>) {
|
||||||
|
if (!sender.canExecute(this, plugin)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.isNotEmpty()) {
|
||||||
|
for (subcommand in subcommands) {
|
||||||
|
if (subcommand.name.equals(args[0], true)) {
|
||||||
|
if (!sender.canExecute(subcommand, plugin)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
subcommand.handleExecution(sender, args.subList(1, args.size))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
notifyFalse(!isPlayersOnly || sender is Player, LangYml.KEY_NOT_PLAYER)
|
||||||
|
|
||||||
|
onExecute(sender, args)
|
||||||
|
|
||||||
|
if (sender is Player) {
|
||||||
|
onExecute(sender, args)
|
||||||
|
}
|
||||||
|
} catch (e: NotificationException) {
|
||||||
|
sender.sendMessage(plugin.langYml.getMessage(e.key))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the tab completion.
|
||||||
|
*
|
||||||
|
* @param sender The sender.
|
||||||
|
* @param args The arguments.
|
||||||
|
* @return The tab completion results.
|
||||||
|
*/
|
||||||
|
private fun CommandBase.handleTabComplete(sender: CommandSender, args: List<String>): List<String> {
|
||||||
|
if (!sender.hasPermission(permission)) return emptyList()
|
||||||
|
|
||||||
|
if (args.size == 1) {
|
||||||
|
val completions = subcommands.filter { sender.hasPermission(it.permission) }.map { it.name }
|
||||||
|
|
||||||
|
val list = mutableListOf<String>()
|
||||||
|
|
||||||
|
StringUtil.copyPartialMatches(args[0], completions, list)
|
||||||
|
if (completions.isNotEmpty()) {
|
||||||
|
return completions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.size >= 2) {
|
||||||
|
val matchingCommand =
|
||||||
|
subcommands.firstOrNull {
|
||||||
|
sender.hasPermission(it.permission) && it.name.equals(args[0], true)
|
||||||
|
}
|
||||||
|
if (matchingCommand != null) {
|
||||||
|
val completions = matchingCommand.handleTabComplete(sender, args.subList(1, args.size)).toMutableList()
|
||||||
|
|
||||||
|
if (sender is Player) {
|
||||||
|
completions.addAll(matchingCommand.handleTabComplete(sender, args.subList(1, args.size)))
|
||||||
|
}
|
||||||
|
|
||||||
|
return completions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val completions = tabComplete(sender, args).toMutableList()
|
||||||
|
if (sender is Player) {
|
||||||
|
completions.addAll(tabComplete(sender, args))
|
||||||
|
}
|
||||||
|
return completions.sorted()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val commandMap: CommandMap
|
||||||
|
get() = try {
|
||||||
|
val fCommandMap = Bukkit.getServer().javaClass.getDeclaredField("commandMap")
|
||||||
|
fCommandMap.trySetAccessible()
|
||||||
|
fCommandMap.get(Bukkit.getServer()) as CommandMap
|
||||||
|
} catch (e: Exception) {
|
||||||
|
throw NullPointerException("Command map wasn't found!")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun CommandSender.canExecute(command: CommandBase, plugin: EcoPlugin): Boolean {
|
||||||
|
if (!this.hasPermission(command.permission) && this is Player) {
|
||||||
|
this.sendMessage(plugin.langYml.noPermission)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
@@ -77,7 +77,7 @@ private abstract class ConfigTypeHandler(
|
|||||||
val type: ConfigType
|
val type: ConfigType
|
||||||
) {
|
) {
|
||||||
fun toMap(input: String?): Map<String, Any?> {
|
fun toMap(input: String?): Map<String, Any?> {
|
||||||
if (input == null || input.isBlank()) {
|
if (input.isNullOrBlank()) {
|
||||||
return emptyMap()
|
return emptyMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package com.willfp.eco.internal.config
|
|||||||
import com.willfp.eco.core.config.ConfigType
|
import com.willfp.eco.core.config.ConfigType
|
||||||
import com.willfp.eco.core.placeholder.InjectablePlaceholder
|
import com.willfp.eco.core.placeholder.InjectablePlaceholder
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
class EcoConfigSection(
|
class EcoConfigSection(
|
||||||
type: ConfigType,
|
type: ConfigType,
|
||||||
values: Map<String, Any?> = emptyMap(),
|
values: Map<String, Any?> = emptyMap(),
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.willfp.eco.internal.gui
|
|||||||
import com.willfp.eco.core.gui.menu.Menu
|
import com.willfp.eco.core.gui.menu.Menu
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
|
// To check in the future, I'm not sure if this is necessary functionality at all.
|
||||||
class MergedStateMenu(
|
class MergedStateMenu(
|
||||||
private val base: Menu,
|
private val base: Menu,
|
||||||
private val additional: Menu
|
private val additional: Menu
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.willfp.eco.core.gui.menu.events.CaptiveItemChangeEvent
|
|||||||
import com.willfp.eco.core.items.isEmpty
|
import com.willfp.eco.core.items.isEmpty
|
||||||
import com.willfp.eco.core.recipe.parts.EmptyTestableItem
|
import com.willfp.eco.core.recipe.parts.EmptyTestableItem
|
||||||
import com.willfp.eco.util.MenuUtils
|
import com.willfp.eco.util.MenuUtils
|
||||||
|
import com.willfp.eco.util.openMenu
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
import org.bukkit.inventory.Inventory
|
import org.bukkit.inventory.Inventory
|
||||||
import org.bukkit.inventory.ItemStack
|
import org.bukkit.inventory.ItemStack
|
||||||
@@ -32,6 +33,14 @@ class RenderedInventory(
|
|||||||
val state = mutableMapOf<String, Any?>()
|
val state = mutableMapOf<String, Any?>()
|
||||||
|
|
||||||
fun render() {
|
fun render() {
|
||||||
|
// This can happen when opening menus from other menus,
|
||||||
|
// fixing a bug where multiple paginated menus on top of
|
||||||
|
// each other caused bugs with page changer display.
|
||||||
|
if (this.menu != player.openMenu) {
|
||||||
|
MenuHandler.unregisterInventory(this.inventory)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val newCaptive = mutableMapOf<GUIPosition, ItemStack>()
|
val newCaptive = mutableMapOf<GUIPosition, ItemStack>()
|
||||||
|
|
||||||
for (row in (1..menu.rows)) {
|
for (row in (1..menu.rows)) {
|
||||||
|
|||||||
@@ -1,20 +1,24 @@
|
|||||||
package com.willfp.eco.internal.gui.slot
|
package com.willfp.eco.internal.gui.slot
|
||||||
|
|
||||||
import com.willfp.eco.core.gui.menu.Menu
|
import com.willfp.eco.core.gui.menu.Menu
|
||||||
|
import com.willfp.eco.core.gui.slot.functional.CaptiveFilter
|
||||||
import com.willfp.eco.core.gui.slot.functional.SlotHandler
|
import com.willfp.eco.core.gui.slot.functional.SlotHandler
|
||||||
import com.willfp.eco.core.gui.slot.functional.SlotProvider
|
import com.willfp.eco.core.gui.slot.functional.SlotProvider
|
||||||
import com.willfp.eco.util.toSingletonList
|
import com.willfp.eco.util.toSingletonList
|
||||||
|
import org.bukkit.Material
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
import org.bukkit.event.inventory.ClickType
|
import org.bukkit.event.inventory.ClickType
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
|
||||||
class EcoCaptiveSlot(
|
class EcoCaptiveSlot(
|
||||||
provider: SlotProvider,
|
provider: SlotProvider,
|
||||||
private val captiveFromEmpty: Boolean,
|
private val captiveFromEmpty: Boolean,
|
||||||
private val notCaptiveFor: (Player) -> Boolean
|
private val notCaptiveFor: (Player) -> Boolean,
|
||||||
|
private val filter: CaptiveFilter
|
||||||
) : EcoSlot(
|
) : EcoSlot(
|
||||||
provider,
|
provider,
|
||||||
ClickType.values().associateWith {
|
ClickType.values().associateWith {
|
||||||
captiveWithTest(notCaptiveFor).toSingletonList()
|
captiveWithTest(notCaptiveFor, filter).toSingletonList()
|
||||||
},
|
},
|
||||||
{ _, _, prev -> prev }
|
{ _, _, prev -> prev }
|
||||||
) {
|
) {
|
||||||
@@ -22,13 +26,25 @@ class EcoCaptiveSlot(
|
|||||||
return !notCaptiveFor(player)
|
return !notCaptiveFor(player)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isAllowedCaptive(player: Player, menu: Menu, itemStack: ItemStack?): Boolean {
|
||||||
|
return filter.isAllowed(player, menu, itemStack)
|
||||||
|
}
|
||||||
|
|
||||||
override fun isCaptiveFromEmpty(): Boolean {
|
override fun isCaptiveFromEmpty(): Boolean {
|
||||||
return captiveFromEmpty
|
return captiveFromEmpty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun captiveWithTest(test: (Player) -> Boolean): SlotHandler {
|
private fun captiveWithTest(
|
||||||
return SlotHandler { event, _, _ ->
|
notCaptiveFor: (Player) -> Boolean,
|
||||||
event.isCancelled = test(event.whoClicked as Player)
|
filter: CaptiveFilter
|
||||||
}
|
): SlotHandler = SlotHandler { event, _, menu ->
|
||||||
|
val player = event.whoClicked as Player
|
||||||
|
|
||||||
|
val item = event.currentItem.nullIfAir() ?: event.cursor.nullIfAir()
|
||||||
|
|
||||||
|
event.isCancelled = !filter.isAllowed(player, menu, item) || notCaptiveFor(player)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun ItemStack?.nullIfAir(): ItemStack? =
|
||||||
|
if (this?.type == Material.AIR) null else this
|
||||||
|
|||||||
@@ -33,9 +33,5 @@ open class EcoSlot(
|
|||||||
return updater.update(player, menu, base) ?: return ItemStack(Material.AIR)
|
return updater.update(player, menu, base) ?: return ItemStack(Material.AIR)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isCaptive(player: Player, menu: Menu): Boolean {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getActionableSlot(player: Player, menu: Menu): EcoSlot = this
|
override fun getActionableSlot(player: Player, menu: Menu): EcoSlot = this
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.willfp.eco.internal.gui.slot
|
|||||||
|
|
||||||
import com.willfp.eco.core.gui.slot.Slot
|
import com.willfp.eco.core.gui.slot.Slot
|
||||||
import com.willfp.eco.core.gui.slot.SlotBuilder
|
import com.willfp.eco.core.gui.slot.SlotBuilder
|
||||||
|
import com.willfp.eco.core.gui.slot.functional.CaptiveFilter
|
||||||
import com.willfp.eco.core.gui.slot.functional.SlotHandler
|
import com.willfp.eco.core.gui.slot.functional.SlotHandler
|
||||||
import com.willfp.eco.core.gui.slot.functional.SlotProvider
|
import com.willfp.eco.core.gui.slot.functional.SlotProvider
|
||||||
import com.willfp.eco.core.gui.slot.functional.SlotUpdater
|
import com.willfp.eco.core.gui.slot.functional.SlotUpdater
|
||||||
@@ -16,7 +17,9 @@ class EcoSlotBuilder(private val provider: SlotProvider) : SlotBuilder {
|
|||||||
|
|
||||||
private val handlers = mutableMapOf<ClickType, MutableList<SlotHandler>>()
|
private val handlers = mutableMapOf<ClickType, MutableList<SlotHandler>>()
|
||||||
|
|
||||||
private var notCaptiveFor: (Player) -> Boolean = { false }
|
private var captiveFilter =
|
||||||
|
CaptiveFilter { _, _, _ -> true }
|
||||||
|
private var notCaptiveFor: (Player) -> Boolean = { _ -> false}
|
||||||
|
|
||||||
override fun onClick(type: ClickType, action: SlotHandler): SlotBuilder {
|
override fun onClick(type: ClickType, action: SlotHandler): SlotBuilder {
|
||||||
handlers.computeIfAbsent(type) { mutableListOf() } += action
|
handlers.computeIfAbsent(type) { mutableListOf() } += action
|
||||||
@@ -24,7 +27,12 @@ class EcoSlotBuilder(private val provider: SlotProvider) : SlotBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun notCaptiveFor(predicate: Predicate<Player>): SlotBuilder {
|
override fun notCaptiveFor(predicate: Predicate<Player>): SlotBuilder {
|
||||||
notCaptiveFor = { predicate.test(it) }
|
notCaptiveFor = { player -> predicate.test(player) }
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setCaptiveFilter(filter: CaptiveFilter): SlotBuilder {
|
||||||
|
captiveFilter = filter
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +52,8 @@ class EcoSlotBuilder(private val provider: SlotProvider) : SlotBuilder {
|
|||||||
EcoCaptiveSlot(
|
EcoCaptiveSlot(
|
||||||
provider,
|
provider,
|
||||||
captiveFromEmpty,
|
captiveFromEmpty,
|
||||||
notCaptiveFor
|
notCaptiveFor,
|
||||||
|
captiveFilter
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
EcoSlot(
|
EcoSlot(
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ object ArgParserName : LookupArgParser {
|
|||||||
|
|
||||||
val formatted = StringUtils.format(name)
|
val formatted = StringUtils.format(name)
|
||||||
|
|
||||||
@Suppress("UsePropertyAccessSyntax")
|
// I don't know why it says it's redundant, the compiler yells at me
|
||||||
|
@Suppress("UsePropertyAccessSyntax", "RedundantSuppression")
|
||||||
meta.setDisplayName(formatted)
|
meta.setDisplayName(formatted)
|
||||||
|
|
||||||
return Predicate {
|
return Predicate {
|
||||||
|
|||||||
@@ -25,18 +25,19 @@ object PriceFactoryXP : PriceFactory {
|
|||||||
) : Price {
|
) : Price {
|
||||||
private val multipliers = mutableMapOf<UUID, Double>()
|
private val multipliers = mutableMapOf<UUID, Double>()
|
||||||
|
|
||||||
override fun canAfford(player: Player) = player.totalExperience >= getValue(player)
|
override fun canAfford(player: Player, multiplier: Double): Boolean =
|
||||||
|
player.totalExperience >= getValue(player, multiplier)
|
||||||
|
|
||||||
override fun pay(player: Player) {
|
override fun pay(player: Player, multiplier: Double) {
|
||||||
player.totalExperience -= getValue(player).roundToInt()
|
player.totalExperience -= getValue(player, multiplier).roundToInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun giveTo(player: Player) {
|
override fun giveTo(player: Player, multiplier: Double) {
|
||||||
player.totalExperience += getValue(player).roundToInt()
|
player.totalExperience += getValue(player, multiplier).roundToInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getValue(player: Player): Double {
|
override fun getValue(player: Player, multiplier: Double): Double {
|
||||||
return xp(MathContext.copyWithPlayer(baseContext, player)) * getMultiplier(player)
|
return xp(MathContext.copyWithPlayer(baseContext, player)) * getMultiplier(player) * multiplier
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getMultiplier(player: Player): Double {
|
override fun getMultiplier(player: Player): Double {
|
||||||
@@ -46,5 +47,9 @@ object PriceFactoryXP : PriceFactory {
|
|||||||
override fun setMultiplier(player: Player, multiplier: Double) {
|
override fun setMultiplier(player: Player, multiplier: Double) {
|
||||||
multipliers[player.uniqueId] = multiplier.roundToInt().toDouble()
|
multipliers[player.uniqueId] = multiplier.roundToInt().toDouble()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getIdentifier(): String {
|
||||||
|
return "eco:xp"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,18 +26,18 @@ object PriceFactoryXPLevels : PriceFactory {
|
|||||||
) : Price {
|
) : Price {
|
||||||
private val multipliers = mutableMapOf<UUID, Double>()
|
private val multipliers = mutableMapOf<UUID, Double>()
|
||||||
|
|
||||||
override fun canAfford(player: Player) = player.level >= getValue(player)
|
override fun canAfford(player: Player, multiplier: Double) = player.level >= getValue(player, multiplier)
|
||||||
|
|
||||||
override fun pay(player: Player) {
|
override fun pay(player: Player, multiplier: Double) {
|
||||||
player.level -= getValue(player).roundToInt()
|
player.level -= getValue(player, multiplier).roundToInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun giveTo(player: Player) {
|
override fun giveTo(player: Player, multiplier: Double) {
|
||||||
player.level += getValue(player).roundToInt()
|
player.level += getValue(player, multiplier).roundToInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getValue(player: Player): Double {
|
override fun getValue(player: Player, multiplier: Double): Double {
|
||||||
return level(MathContext.copyWithPlayer(baseContext, player)) * getMultiplier(player)
|
return level(MathContext.copyWithPlayer(baseContext, player)) * getMultiplier(player) * multiplier
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getMultiplier(player: Player): Double {
|
override fun getMultiplier(player: Player): Double {
|
||||||
@@ -47,5 +47,9 @@ object PriceFactoryXPLevels : PriceFactory {
|
|||||||
override fun setMultiplier(player: Player, multiplier: Double) {
|
override fun setMultiplier(player: Player, multiplier: Double) {
|
||||||
multipliers[player.uniqueId] = multiplier.roundToInt().toDouble()
|
multipliers[player.uniqueId] = multiplier.roundToInt().toDouble()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getIdentifier(): String {
|
||||||
|
return "eco:xp-levels"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import com.willfp.eco.core.entities.ai.EntityGoal
|
|||||||
import com.willfp.eco.core.entities.ai.TargetGoal
|
import com.willfp.eco.core.entities.ai.TargetGoal
|
||||||
import com.willfp.eco.internal.spigot.proxy.common.ai.EntityGoalFactory
|
import com.willfp.eco.internal.spigot.proxy.common.ai.EntityGoalFactory
|
||||||
import com.willfp.eco.internal.spigot.proxy.common.ai.TargetGoalFactory
|
import com.willfp.eco.internal.spigot.proxy.common.ai.TargetGoalFactory
|
||||||
import net.minecraft.core.Registry
|
|
||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.nbt.CompoundTag
|
||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
import net.minecraft.world.entity.LivingEntity
|
import net.minecraft.world.entity.LivingEntity
|
||||||
@@ -48,17 +47,14 @@ private val MATERIAL_TO_ITEM = mutableMapOf<Material, Item>()
|
|||||||
|
|
||||||
fun Material.toItem(): Item =
|
fun Material.toItem(): Item =
|
||||||
MATERIAL_TO_ITEM.getOrPut(this) {
|
MATERIAL_TO_ITEM.getOrPut(this) {
|
||||||
Registry.ITEM.getOptional(this.key.toResourceLocation())
|
impl.materialToItem(this)
|
||||||
.orElseThrow { IllegalArgumentException("Material is not item!") }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val ITEM_TO_MATERIAL = mutableMapOf<Item, Material>()
|
private val ITEM_TO_MATERIAL = mutableMapOf<Item, Material>()
|
||||||
|
|
||||||
fun Item.toMaterial(): Material =
|
fun Item.toMaterial(): Material =
|
||||||
ITEM_TO_MATERIAL.getOrPut(this) {
|
ITEM_TO_MATERIAL.getOrPut(this) {
|
||||||
val material = Material.getMaterial(Registry.ITEM.getKey(this).path.uppercase())
|
impl.itemToMaterial(this)
|
||||||
?: throw IllegalArgumentException("Invalid material!")
|
|
||||||
material
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun CompoundTag.makePdc(base: Boolean = false): PersistentDataContainer =
|
fun CompoundTag.makePdc(base: Boolean = false): PersistentDataContainer =
|
||||||
@@ -94,6 +90,10 @@ interface CommonsProvider {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun materialToItem(material: Material): Item
|
||||||
|
|
||||||
|
fun itemToMaterial(item: Item): Material
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun setIfNeeded(provider: CommonsProvider) {
|
fun setIfNeeded(provider: CommonsProvider) {
|
||||||
if (::impl.isInitialized) {
|
if (::impl.isInitialized) {
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ private class EnhancedInteractGoal(
|
|||||||
return if (mob.random.nextFloat() >= probability) {
|
return if (mob.random.nextFloat() >= probability) {
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
@Suppress("SENSELESS_COMPARISON")
|
|
||||||
if (mob.target != null) {
|
if (mob.target != null) {
|
||||||
lookAt = mob.target
|
lookAt = mob.target
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ private class EnhancedHurtByTargetGoal(
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
|
|
||||||
return super.canAttack(target, targetPredicate)
|
return super.canAttack(target, targetPredicate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ class EcoFastItemStack(
|
|||||||
apply()
|
apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNNECESSARY_NOT_NULL_ASSERTION")
|
@Suppress("RedundantSuppression", "UNNECESSARY_NOT_NULL_ASSERTION")
|
||||||
private var flagBits: Byte
|
private var flagBits: Byte
|
||||||
get() =
|
get() =
|
||||||
if (handle.hasTag() && handle.getTag()!!.contains(
|
if (handle.hasTag() && handle.getTag()!!.contains(
|
||||||
@@ -255,7 +255,7 @@ class EcoFastItemStack(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
override fun hashCode(): Int {
|
||||||
@Suppress("UNNECESSARY_SAFE_CALL")
|
@Suppress("RedundantSuppression", "UNNECESSARY_SAFE_CALL")
|
||||||
return handle.getTag()?.hashCode() ?: (0b00010101 * 31 + Item.getId(handle.getItem()))
|
return handle.getTag()?.hashCode() ?: (0b00010101 * 31 + Item.getId(handle.getItem()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_17_R1
|
||||||
|
|
||||||
|
import com.willfp.eco.core.command.impl.PluginCommand
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.BukkitCommandsProxy
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.command.Command
|
||||||
|
import org.bukkit.command.SimpleCommandMap
|
||||||
|
import org.bukkit.craftbukkit.v1_17_R1.CraftServer
|
||||||
|
import java.lang.reflect.Field
|
||||||
|
|
||||||
|
class BukkitCommands : BukkitCommandsProxy {
|
||||||
|
private val knownCommandsField: Field by lazy {
|
||||||
|
SimpleCommandMap::class.java.getDeclaredField("knownCommands")
|
||||||
|
.apply {
|
||||||
|
isAccessible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
private val knownCommands: MutableMap<String, Command>
|
||||||
|
get() = knownCommandsField.get(getCommandMap()) as MutableMap<String, Command>
|
||||||
|
|
||||||
|
override fun getCommandMap(): SimpleCommandMap {
|
||||||
|
return (Bukkit.getServer() as CraftServer).commandMap
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun syncCommands() {
|
||||||
|
(Bukkit.getServer() as CraftServer).syncCommands()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun unregisterCommand(command: PluginCommand) {
|
||||||
|
knownCommands.remove(command.name)
|
||||||
|
knownCommands.remove("${command.plugin.name.lowercase()}:${command.name}")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,11 +2,15 @@ package com.willfp.eco.internal.spigot.proxy.v1_17_R1
|
|||||||
|
|
||||||
import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
|
import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
|
||||||
import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
|
import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.common.toResourceLocation
|
||||||
|
import net.minecraft.core.Registry
|
||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.nbt.CompoundTag
|
||||||
import net.minecraft.nbt.Tag
|
import net.minecraft.nbt.Tag
|
||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
import net.minecraft.world.entity.PathfinderMob
|
import net.minecraft.world.entity.PathfinderMob
|
||||||
|
import net.minecraft.world.item.Item
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.Material
|
||||||
import org.bukkit.NamespacedKey
|
import org.bukkit.NamespacedKey
|
||||||
import org.bukkit.craftbukkit.v1_17_R1.CraftServer
|
import org.bukkit.craftbukkit.v1_17_R1.CraftServer
|
||||||
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftEntity
|
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftEntity
|
||||||
@@ -131,5 +135,13 @@ class CommonsInitializer : CommonsInitializerProxy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun materialToItem(material: Material): Item =
|
||||||
|
Registry.ITEM.getOptional(material.key.toResourceLocation())
|
||||||
|
.orElseThrow { IllegalArgumentException("Material is not item!") }
|
||||||
|
|
||||||
|
override fun itemToMaterial(item: Item) =
|
||||||
|
Material.getMaterial(Registry.ITEM.getKey(item).path.uppercase())
|
||||||
|
?: throw IllegalArgumentException("Invalid material!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import org.bukkit.persistence.PersistentDataContainer
|
|||||||
import org.bukkit.persistence.PersistentDataType
|
import org.bukkit.persistence.PersistentDataType
|
||||||
|
|
||||||
class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFactoryProxy {
|
class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFactoryProxy {
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
private val registry: CraftPersistentDataTypeRegistry
|
private val registry: CraftPersistentDataTypeRegistry
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -38,7 +37,7 @@ class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFa
|
|||||||
}
|
}
|
||||||
|
|
||||||
inner class EcoPersistentDataContainer(
|
inner class EcoPersistentDataContainer(
|
||||||
val handle: CraftPersistentDataContainer
|
private val handle: CraftPersistentDataContainer
|
||||||
) : ExtendedPersistentDataContainer {
|
) : ExtendedPersistentDataContainer {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
private val customDataTags: MutableMap<String, Tag> =
|
private val customDataTags: MutableMap<String, Tag> =
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
package com.willfp.eco.internal.spigot.proxy.v1_17_R1
|
|
||||||
|
|
||||||
import com.willfp.eco.internal.spigot.proxy.SyncCommandsProxy
|
|
||||||
import org.bukkit.Bukkit
|
|
||||||
import org.bukkit.craftbukkit.v1_17_R1.CraftServer
|
|
||||||
|
|
||||||
class SyncCommands : SyncCommandsProxy {
|
|
||||||
override fun syncCommands() {
|
|
||||||
(Bukkit.getServer() as CraftServer).syncCommands()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_18_R1
|
||||||
|
|
||||||
|
import com.willfp.eco.core.command.impl.PluginCommand
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.BukkitCommandsProxy
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.command.Command
|
||||||
|
import org.bukkit.command.SimpleCommandMap
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.CraftServer
|
||||||
|
import java.lang.reflect.Field
|
||||||
|
|
||||||
|
class BukkitCommands : BukkitCommandsProxy {
|
||||||
|
private val knownCommandsField: Field by lazy {
|
||||||
|
SimpleCommandMap::class.java.getDeclaredField("knownCommands")
|
||||||
|
.apply {
|
||||||
|
isAccessible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
private val knownCommands: MutableMap<String, Command>
|
||||||
|
get() = knownCommandsField.get(getCommandMap()) as MutableMap<String, Command>
|
||||||
|
|
||||||
|
override fun getCommandMap(): SimpleCommandMap {
|
||||||
|
return (Bukkit.getServer() as CraftServer).commandMap
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun syncCommands() {
|
||||||
|
(Bukkit.getServer() as CraftServer).syncCommands()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun unregisterCommand(command: PluginCommand) {
|
||||||
|
knownCommands.remove(command.name)
|
||||||
|
knownCommands.remove("${command.plugin.name.lowercase()}:${command.name}")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,11 +2,15 @@ package com.willfp.eco.internal.spigot.proxy.v1_18_R1
|
|||||||
|
|
||||||
import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
|
import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
|
||||||
import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
|
import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.common.toResourceLocation
|
||||||
|
import net.minecraft.core.Registry
|
||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.nbt.CompoundTag
|
||||||
import net.minecraft.nbt.Tag
|
import net.minecraft.nbt.Tag
|
||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
import net.minecraft.world.entity.PathfinderMob
|
import net.minecraft.world.entity.PathfinderMob
|
||||||
|
import net.minecraft.world.item.Item
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.Material
|
||||||
import org.bukkit.NamespacedKey
|
import org.bukkit.NamespacedKey
|
||||||
import org.bukkit.craftbukkit.v1_18_R1.CraftServer
|
import org.bukkit.craftbukkit.v1_18_R1.CraftServer
|
||||||
import org.bukkit.craftbukkit.v1_18_R1.entity.CraftEntity
|
import org.bukkit.craftbukkit.v1_18_R1.entity.CraftEntity
|
||||||
@@ -131,5 +135,13 @@ class CommonsInitializer : CommonsInitializerProxy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun materialToItem(material: Material): Item =
|
||||||
|
Registry.ITEM.getOptional(material.key.toResourceLocation())
|
||||||
|
.orElseThrow { IllegalArgumentException("Material is not item!") }
|
||||||
|
|
||||||
|
override fun itemToMaterial(item: Item) =
|
||||||
|
Material.getMaterial(Registry.ITEM.getKey(item).path.uppercase())
|
||||||
|
?: throw IllegalArgumentException("Invalid material!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import org.bukkit.persistence.PersistentDataContainer
|
|||||||
import org.bukkit.persistence.PersistentDataType
|
import org.bukkit.persistence.PersistentDataType
|
||||||
|
|
||||||
class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFactoryProxy {
|
class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFactoryProxy {
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
private val registry: CraftPersistentDataTypeRegistry
|
private val registry: CraftPersistentDataTypeRegistry
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -38,7 +37,7 @@ class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFa
|
|||||||
}
|
}
|
||||||
|
|
||||||
inner class EcoPersistentDataContainer(
|
inner class EcoPersistentDataContainer(
|
||||||
val handle: CraftPersistentDataContainer
|
private val handle: CraftPersistentDataContainer
|
||||||
) : ExtendedPersistentDataContainer {
|
) : ExtendedPersistentDataContainer {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
private val customDataTags: MutableMap<String, Tag> =
|
private val customDataTags: MutableMap<String, Tag> =
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
package com.willfp.eco.internal.spigot.proxy.v1_18_R1
|
|
||||||
|
|
||||||
import com.willfp.eco.internal.spigot.proxy.SyncCommandsProxy
|
|
||||||
import org.bukkit.Bukkit
|
|
||||||
import org.bukkit.craftbukkit.v1_18_R1.CraftServer
|
|
||||||
|
|
||||||
class SyncCommands : SyncCommandsProxy {
|
|
||||||
override fun syncCommands() {
|
|
||||||
(Bukkit.getServer() as CraftServer).syncCommands()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_18_R2
|
||||||
|
|
||||||
|
import com.willfp.eco.core.command.impl.PluginCommand
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.BukkitCommandsProxy
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.command.Command
|
||||||
|
import org.bukkit.command.SimpleCommandMap
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R2.CraftServer
|
||||||
|
import java.lang.reflect.Field
|
||||||
|
|
||||||
|
class BukkitCommands : BukkitCommandsProxy {
|
||||||
|
private val knownCommandsField: Field by lazy {
|
||||||
|
SimpleCommandMap::class.java.getDeclaredField("knownCommands")
|
||||||
|
.apply {
|
||||||
|
isAccessible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
private val knownCommands: MutableMap<String, Command>
|
||||||
|
get() = knownCommandsField.get(getCommandMap()) as MutableMap<String, Command>
|
||||||
|
|
||||||
|
override fun getCommandMap(): SimpleCommandMap {
|
||||||
|
return (Bukkit.getServer() as CraftServer).commandMap
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun syncCommands() {
|
||||||
|
(Bukkit.getServer() as CraftServer).syncCommands()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun unregisterCommand(command: PluginCommand) {
|
||||||
|
knownCommands.remove(command.name)
|
||||||
|
knownCommands.remove("${command.plugin.name.lowercase()}:${command.name}")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,11 +2,15 @@ package com.willfp.eco.internal.spigot.proxy.v1_18_R2
|
|||||||
|
|
||||||
import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
|
import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
|
||||||
import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
|
import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.common.toResourceLocation
|
||||||
|
import net.minecraft.core.Registry
|
||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.nbt.CompoundTag
|
||||||
import net.minecraft.nbt.Tag
|
import net.minecraft.nbt.Tag
|
||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
import net.minecraft.world.entity.PathfinderMob
|
import net.minecraft.world.entity.PathfinderMob
|
||||||
|
import net.minecraft.world.item.Item
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.Material
|
||||||
import org.bukkit.NamespacedKey
|
import org.bukkit.NamespacedKey
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.CraftServer
|
import org.bukkit.craftbukkit.v1_18_R2.CraftServer
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftEntity
|
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftEntity
|
||||||
@@ -131,5 +135,13 @@ class CommonsInitializer : CommonsInitializerProxy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun materialToItem(material: Material): Item =
|
||||||
|
Registry.ITEM.getOptional(material.key.toResourceLocation())
|
||||||
|
.orElseThrow { IllegalArgumentException("Material is not item!") }
|
||||||
|
|
||||||
|
override fun itemToMaterial(item: Item) =
|
||||||
|
Material.getMaterial(Registry.ITEM.getKey(item).path.uppercase())
|
||||||
|
?: throw IllegalArgumentException("Invalid material!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import org.bukkit.persistence.PersistentDataContainer
|
|||||||
import org.bukkit.persistence.PersistentDataType
|
import org.bukkit.persistence.PersistentDataType
|
||||||
|
|
||||||
class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFactoryProxy {
|
class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFactoryProxy {
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
private val registry: CraftPersistentDataTypeRegistry
|
private val registry: CraftPersistentDataTypeRegistry
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -38,7 +37,7 @@ class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFa
|
|||||||
}
|
}
|
||||||
|
|
||||||
inner class EcoPersistentDataContainer(
|
inner class EcoPersistentDataContainer(
|
||||||
val handle: CraftPersistentDataContainer
|
private val handle: CraftPersistentDataContainer
|
||||||
) : ExtendedPersistentDataContainer {
|
) : ExtendedPersistentDataContainer {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
private val customDataTags: MutableMap<String, Tag> =
|
private val customDataTags: MutableMap<String, Tag> =
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
package com.willfp.eco.internal.spigot.proxy.v1_18_R2
|
|
||||||
|
|
||||||
import com.willfp.eco.internal.spigot.proxy.SyncCommandsProxy
|
|
||||||
import org.bukkit.Bukkit
|
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.CraftServer
|
|
||||||
|
|
||||||
class SyncCommands : SyncCommandsProxy {
|
|
||||||
override fun syncCommands() {
|
|
||||||
(Bukkit.getServer() as CraftServer).syncCommands()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_19_R1
|
||||||
|
|
||||||
|
import com.willfp.eco.core.command.impl.PluginCommand
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.BukkitCommandsProxy
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.command.Command
|
||||||
|
import org.bukkit.command.SimpleCommandMap
|
||||||
|
import org.bukkit.craftbukkit.v1_19_R1.CraftServer
|
||||||
|
import java.lang.reflect.Field
|
||||||
|
|
||||||
|
class BukkitCommands : BukkitCommandsProxy {
|
||||||
|
private val knownCommandsField: Field by lazy {
|
||||||
|
SimpleCommandMap::class.java.getDeclaredField("knownCommands")
|
||||||
|
.apply {
|
||||||
|
isAccessible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
private val knownCommands: MutableMap<String, Command>
|
||||||
|
get() = knownCommandsField.get(getCommandMap()) as MutableMap<String, Command>
|
||||||
|
|
||||||
|
override fun getCommandMap(): SimpleCommandMap {
|
||||||
|
return (Bukkit.getServer() as CraftServer).commandMap
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun syncCommands() {
|
||||||
|
(Bukkit.getServer() as CraftServer).syncCommands()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun unregisterCommand(command: PluginCommand) {
|
||||||
|
knownCommands.remove(command.name)
|
||||||
|
knownCommands.remove("${command.plugin.name.lowercase()}:${command.name}")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,11 +2,15 @@ package com.willfp.eco.internal.spigot.proxy.v1_19_R1
|
|||||||
|
|
||||||
import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
|
import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
|
||||||
import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
|
import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.common.toResourceLocation
|
||||||
|
import net.minecraft.core.Registry
|
||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.nbt.CompoundTag
|
||||||
import net.minecraft.nbt.Tag
|
import net.minecraft.nbt.Tag
|
||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
import net.minecraft.world.entity.PathfinderMob
|
import net.minecraft.world.entity.PathfinderMob
|
||||||
|
import net.minecraft.world.item.Item
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.Material
|
||||||
import org.bukkit.NamespacedKey
|
import org.bukkit.NamespacedKey
|
||||||
import org.bukkit.craftbukkit.v1_19_R1.CraftServer
|
import org.bukkit.craftbukkit.v1_19_R1.CraftServer
|
||||||
import org.bukkit.craftbukkit.v1_19_R1.entity.CraftEntity
|
import org.bukkit.craftbukkit.v1_19_R1.entity.CraftEntity
|
||||||
@@ -131,5 +135,13 @@ class CommonsInitializer : CommonsInitializerProxy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun materialToItem(material: Material): Item =
|
||||||
|
Registry.ITEM.getOptional(material.key.toResourceLocation())
|
||||||
|
.orElseThrow { IllegalArgumentException("Material is not item!") }
|
||||||
|
|
||||||
|
override fun itemToMaterial(item: Item) =
|
||||||
|
Material.getMaterial(Registry.ITEM.getKey(item).path.uppercase())
|
||||||
|
?: throw IllegalArgumentException("Invalid material!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import org.bukkit.persistence.PersistentDataContainer
|
|||||||
import org.bukkit.persistence.PersistentDataType
|
import org.bukkit.persistence.PersistentDataType
|
||||||
|
|
||||||
class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFactoryProxy {
|
class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFactoryProxy {
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
private val registry: CraftPersistentDataTypeRegistry
|
private val registry: CraftPersistentDataTypeRegistry
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -38,7 +37,7 @@ class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFa
|
|||||||
}
|
}
|
||||||
|
|
||||||
inner class EcoPersistentDataContainer(
|
inner class EcoPersistentDataContainer(
|
||||||
val handle: CraftPersistentDataContainer
|
private val handle: CraftPersistentDataContainer
|
||||||
) : ExtendedPersistentDataContainer {
|
) : ExtendedPersistentDataContainer {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
private val customDataTags: MutableMap<String, Tag> =
|
private val customDataTags: MutableMap<String, Tag> =
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
package com.willfp.eco.internal.spigot.proxy.v1_19_R1
|
|
||||||
|
|
||||||
import com.willfp.eco.internal.spigot.proxy.SyncCommandsProxy
|
|
||||||
import org.bukkit.Bukkit
|
|
||||||
import org.bukkit.craftbukkit.v1_19_R1.CraftServer
|
|
||||||
|
|
||||||
class SyncCommands : SyncCommandsProxy {
|
|
||||||
override fun syncCommands() {
|
|
||||||
(Bukkit.getServer() as CraftServer).syncCommands()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
39
eco-core/core-nms/v1_19_R2/build.gradle.kts
Normal file
39
eco-core/core-nms/v1_19_R2/build.gradle.kts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
plugins {
|
||||||
|
id("io.papermc.paperweight.userdev") version "1.3.6"
|
||||||
|
}
|
||||||
|
|
||||||
|
group = "com.willfp"
|
||||||
|
version = rootProject.version
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation(project(":eco-core:core-nms:nms-common"))
|
||||||
|
paperDevBundle("1.19.3-R0.1-SNAPSHOT")
|
||||||
|
|
||||||
|
implementation("net.kyori:adventure-text-minimessage:4.11.0") {
|
||||||
|
version {
|
||||||
|
strictly("4.11.0")
|
||||||
|
}
|
||||||
|
exclude(group = "net.kyori", module = "adventure-api")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
build {
|
||||||
|
dependsOn(reobfJar)
|
||||||
|
}
|
||||||
|
|
||||||
|
reobfJar {
|
||||||
|
mustRunAfter(shadowJar)
|
||||||
|
}
|
||||||
|
|
||||||
|
shadowJar {
|
||||||
|
relocate(
|
||||||
|
"com.willfp.eco.internal.spigot.proxy.common",
|
||||||
|
"com.willfp.eco.internal.spigot.proxy.v1_19_R2.common"
|
||||||
|
)
|
||||||
|
relocate(
|
||||||
|
"net.kyori.adventure.text.minimessage",
|
||||||
|
"com.willfp.eco.internal.spigot.proxy.v1_19_R2.minimessage"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_19_R2
|
||||||
|
|
||||||
|
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")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_19_R2
|
||||||
|
|
||||||
|
import com.willfp.eco.core.command.impl.PluginCommand
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.BukkitCommandsProxy
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.command.Command
|
||||||
|
import org.bukkit.command.SimpleCommandMap
|
||||||
|
import org.bukkit.craftbukkit.v1_19_R2.CraftServer
|
||||||
|
import java.lang.reflect.Field
|
||||||
|
|
||||||
|
class BukkitCommands : BukkitCommandsProxy {
|
||||||
|
private val knownCommandsField: Field by lazy {
|
||||||
|
SimpleCommandMap::class.java.getDeclaredField("knownCommands")
|
||||||
|
.apply {
|
||||||
|
isAccessible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
private val knownCommands: MutableMap<String, Command>
|
||||||
|
get() = knownCommandsField.get(getCommandMap()) as MutableMap<String, Command>
|
||||||
|
|
||||||
|
override fun getCommandMap(): SimpleCommandMap {
|
||||||
|
return (Bukkit.getServer() as CraftServer).commandMap
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun syncCommands() {
|
||||||
|
(Bukkit.getServer() as CraftServer).syncCommands()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun unregisterCommand(command: PluginCommand) {
|
||||||
|
knownCommands.remove(command.name)
|
||||||
|
knownCommands.remove("${command.plugin.name.lowercase()}:${command.name}")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_19_R2
|
||||||
|
|
||||||
|
import com.willfp.eco.core.display.Display
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.ChatComponentProxy
|
||||||
|
import net.kyori.adventure.nbt.api.BinaryTagHolder
|
||||||
|
import net.kyori.adventure.text.BuildableComponent
|
||||||
|
import net.kyori.adventure.text.Component
|
||||||
|
import net.kyori.adventure.text.TranslatableComponent
|
||||||
|
import net.kyori.adventure.text.event.HoverEvent
|
||||||
|
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer
|
||||||
|
import net.minecraft.nbt.TagParser
|
||||||
|
import org.bukkit.Material
|
||||||
|
import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftItemStack
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
class ChatComponent : ChatComponentProxy {
|
||||||
|
private val gsonComponentSerializer = GsonComponentSerializer.gson()
|
||||||
|
|
||||||
|
override fun modifyComponent(obj: Any, player: Player): Any {
|
||||||
|
if (obj !is net.minecraft.network.chat.Component) {
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
|
||||||
|
val component = gsonComponentSerializer.deserialize(
|
||||||
|
net.minecraft.network.chat.Component.Serializer.toJson(
|
||||||
|
obj
|
||||||
|
)
|
||||||
|
).asComponent() as BuildableComponent<*, *>
|
||||||
|
|
||||||
|
val newComponent = modifyBaseComponent(component, player)
|
||||||
|
|
||||||
|
return net.minecraft.network.chat.Component.Serializer.fromJson(
|
||||||
|
gsonComponentSerializer.serialize(newComponent.asComponent())
|
||||||
|
) ?: obj
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun modifyBaseComponent(baseComponent: Component, player: Player): Component {
|
||||||
|
var component = baseComponent
|
||||||
|
|
||||||
|
if (component is TranslatableComponent) {
|
||||||
|
val args = mutableListOf<Component>()
|
||||||
|
for (arg in component.args()) {
|
||||||
|
args.add(modifyBaseComponent(arg, player))
|
||||||
|
}
|
||||||
|
component = component.args(args)
|
||||||
|
}
|
||||||
|
|
||||||
|
val children = mutableListOf<Component>()
|
||||||
|
for (child in component.children()) {
|
||||||
|
children.add(modifyBaseComponent(child, player))
|
||||||
|
}
|
||||||
|
component = component.children(children)
|
||||||
|
|
||||||
|
val hoverEvent: HoverEvent<Any> = component.style().hoverEvent() as HoverEvent<Any>? ?: return component
|
||||||
|
|
||||||
|
val showItem = hoverEvent.value()
|
||||||
|
|
||||||
|
if (showItem !is HoverEvent.ShowItem) {
|
||||||
|
return component
|
||||||
|
}
|
||||||
|
|
||||||
|
val newShowItem = showItem.nbt(
|
||||||
|
BinaryTagHolder.binaryTagHolder(
|
||||||
|
CraftItemStack.asNMSCopy(
|
||||||
|
Display.display(
|
||||||
|
CraftItemStack.asBukkitCopy(
|
||||||
|
CraftItemStack.asNMSCopy(
|
||||||
|
ItemStack(
|
||||||
|
Material.matchMaterial(
|
||||||
|
showItem.item()
|
||||||
|
.toString()
|
||||||
|
) ?: return component,
|
||||||
|
showItem.count()
|
||||||
|
)
|
||||||
|
).apply {
|
||||||
|
this.tag = TagParser.parseTag(
|
||||||
|
showItem.nbt()?.string() ?: return component
|
||||||
|
) ?: return component
|
||||||
|
}
|
||||||
|
),
|
||||||
|
player
|
||||||
|
)
|
||||||
|
).orCreateTag.toString()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
val newHover = hoverEvent.value(newShowItem)
|
||||||
|
val style = component.style().hoverEvent(newHover)
|
||||||
|
return component.style(style)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_19_R2
|
||||||
|
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.common.toResourceLocation
|
||||||
|
import net.minecraft.core.registries.BuiltInRegistries
|
||||||
|
import net.minecraft.nbt.CompoundTag
|
||||||
|
import net.minecraft.nbt.Tag
|
||||||
|
import net.minecraft.resources.ResourceLocation
|
||||||
|
import net.minecraft.world.entity.PathfinderMob
|
||||||
|
import net.minecraft.world.item.Item
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.Material
|
||||||
|
import org.bukkit.NamespacedKey
|
||||||
|
import org.bukkit.craftbukkit.v1_19_R2.CraftServer
|
||||||
|
import org.bukkit.craftbukkit.v1_19_R2.entity.CraftEntity
|
||||||
|
import org.bukkit.craftbukkit.v1_19_R2.entity.CraftMob
|
||||||
|
import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftItemStack
|
||||||
|
import org.bukkit.craftbukkit.v1_19_R2.persistence.CraftPersistentDataContainer
|
||||||
|
import org.bukkit.craftbukkit.v1_19_R2.persistence.CraftPersistentDataTypeRegistry
|
||||||
|
import org.bukkit.craftbukkit.v1_19_R2.util.CraftMagicNumbers
|
||||||
|
import org.bukkit.craftbukkit.v1_19_R2.util.CraftNamespacedKey
|
||||||
|
import org.bukkit.entity.LivingEntity
|
||||||
|
import org.bukkit.entity.Mob
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
import org.bukkit.persistence.PersistentDataContainer
|
||||||
|
import java.lang.reflect.Field
|
||||||
|
|
||||||
|
class CommonsInitializer : CommonsInitializerProxy {
|
||||||
|
override fun init() {
|
||||||
|
CommonsProvider.setIfNeeded(CommonsProviderImpl)
|
||||||
|
}
|
||||||
|
|
||||||
|
object CommonsProviderImpl : CommonsProvider {
|
||||||
|
private val cisHandle: Field = CraftItemStack::class.java.getDeclaredField("handle").apply {
|
||||||
|
isAccessible = true
|
||||||
|
}
|
||||||
|
|
||||||
|
private val pdcRegsitry = Class.forName("org.bukkit.craftbukkit.v1_19_R2.inventory.CraftMetaItem")
|
||||||
|
.getDeclaredField("DATA_TYPE_REGISTRY")
|
||||||
|
.apply { isAccessible = true }
|
||||||
|
.get(null) as CraftPersistentDataTypeRegistry
|
||||||
|
|
||||||
|
override val nbtTagString = CraftMagicNumbers.NBT.TAG_STRING
|
||||||
|
|
||||||
|
override fun toPathfinderMob(mob: Mob): PathfinderMob? {
|
||||||
|
val craft = mob as? CraftMob ?: return null
|
||||||
|
return craft.handle as? PathfinderMob
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toResourceLocation(namespacedKey: NamespacedKey): ResourceLocation =
|
||||||
|
CraftNamespacedKey.toMinecraft(namespacedKey)
|
||||||
|
|
||||||
|
override fun asNMSStack(itemStack: ItemStack): net.minecraft.world.item.ItemStack {
|
||||||
|
return if (itemStack !is CraftItemStack) {
|
||||||
|
CraftItemStack.asNMSCopy(itemStack)
|
||||||
|
} else {
|
||||||
|
cisHandle[itemStack] as net.minecraft.world.item.ItemStack? ?: CraftItemStack.asNMSCopy(itemStack)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun asBukkitStack(itemStack: net.minecraft.world.item.ItemStack): ItemStack {
|
||||||
|
return CraftItemStack.asBukkitCopy(itemStack)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun mergeIfNeeded(itemStack: ItemStack, nmsStack: net.minecraft.world.item.ItemStack) {
|
||||||
|
if (itemStack !is CraftItemStack) {
|
||||||
|
itemStack.itemMeta = CraftItemStack.asCraftMirror(nmsStack).itemMeta
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toBukkitEntity(entity: net.minecraft.world.entity.LivingEntity): LivingEntity? =
|
||||||
|
CraftEntity.getEntity(Bukkit.getServer() as CraftServer, entity) as? LivingEntity
|
||||||
|
|
||||||
|
override fun makePdc(tag: CompoundTag, base: Boolean): PersistentDataContainer {
|
||||||
|
fun emptyPdc(): CraftPersistentDataContainer = CraftPersistentDataContainer(pdcRegsitry)
|
||||||
|
|
||||||
|
fun CompoundTag?.toPdc(): PersistentDataContainer {
|
||||||
|
val pdc = emptyPdc()
|
||||||
|
this ?: return pdc
|
||||||
|
val keys = this.allKeys
|
||||||
|
for (key in keys) {
|
||||||
|
pdc.put(key, this[key])
|
||||||
|
}
|
||||||
|
|
||||||
|
return pdc
|
||||||
|
}
|
||||||
|
|
||||||
|
return if (base) {
|
||||||
|
tag.toPdc()
|
||||||
|
} else {
|
||||||
|
if (tag.contains("PublicBukkitValues")) {
|
||||||
|
tag.getCompound("PublicBukkitValues").toPdc()
|
||||||
|
} else {
|
||||||
|
emptyPdc()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setPdc(
|
||||||
|
tag: CompoundTag,
|
||||||
|
pdc: PersistentDataContainer?,
|
||||||
|
item: net.minecraft.world.item.ItemStack?
|
||||||
|
) {
|
||||||
|
fun CraftPersistentDataContainer.toTag(): CompoundTag {
|
||||||
|
val compound = CompoundTag()
|
||||||
|
val rawPublicMap: Map<String, Tag> = this.raw
|
||||||
|
for ((key, value) in rawPublicMap) {
|
||||||
|
compound.put(key, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
return compound
|
||||||
|
}
|
||||||
|
|
||||||
|
val container = when (pdc) {
|
||||||
|
is CraftPersistentDataContainer? -> pdc
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item != null) {
|
||||||
|
if (container != null && !container.isEmpty) {
|
||||||
|
for (key in tag.allKeys.toSet()) {
|
||||||
|
tag.remove(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
tag.merge(container.toTag())
|
||||||
|
} else {
|
||||||
|
item.tag = null
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (container != null && !container.isEmpty) {
|
||||||
|
tag.put("PublicBukkitValues", container.toTag())
|
||||||
|
} else {
|
||||||
|
tag.remove("PublicBukkitValues")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun materialToItem(material: Material): Item =
|
||||||
|
BuiltInRegistries.ITEM.getOptional(material.key.toResourceLocation())
|
||||||
|
.orElseThrow { IllegalArgumentException("Material is not item!") }
|
||||||
|
|
||||||
|
override fun itemToMaterial(item: Item) =
|
||||||
|
Material.getMaterial(BuiltInRegistries.ITEM.getKey(item).path.uppercase())
|
||||||
|
?: throw IllegalArgumentException("Invalid material!")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_19_R2
|
||||||
|
|
||||||
|
import com.willfp.eco.internal.entities.EcoDummyEntity
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.DummyEntityFactoryProxy
|
||||||
|
import org.bukkit.Location
|
||||||
|
import org.bukkit.craftbukkit.v1_19_R2.CraftWorld
|
||||||
|
import org.bukkit.entity.Entity
|
||||||
|
import org.bukkit.entity.EntityType
|
||||||
|
|
||||||
|
class DummyEntityFactory : DummyEntityFactoryProxy {
|
||||||
|
override fun createDummyEntity(location: Location): Entity {
|
||||||
|
val world = location.world as CraftWorld
|
||||||
|
@Suppress("UsePropertyAccessSyntax")
|
||||||
|
return EcoDummyEntity(world.createEntity(location, EntityType.ZOMBIE.entityClass).getBukkitEntity())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_19_R2
|
||||||
|
|
||||||
|
import com.willfp.eco.core.entities.ai.EntityController
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.EntityControllerFactoryProxy
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.common.ai.EcoEntityController
|
||||||
|
import org.bukkit.entity.Mob
|
||||||
|
|
||||||
|
class EntityControllerFactory : EntityControllerFactoryProxy {
|
||||||
|
override fun <T : Mob> createEntityController(entity: T): EntityController<T> {
|
||||||
|
return EcoEntityController(entity)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_19_R2
|
||||||
|
|
||||||
|
import com.willfp.eco.core.data.ExtendedPersistentDataContainer
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.ExtendedPersistentDataContainerFactoryProxy
|
||||||
|
import net.minecraft.nbt.Tag
|
||||||
|
import org.bukkit.Material
|
||||||
|
import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftItemStack
|
||||||
|
import org.bukkit.craftbukkit.v1_19_R2.persistence.CraftPersistentDataContainer
|
||||||
|
import org.bukkit.craftbukkit.v1_19_R2.persistence.CraftPersistentDataTypeRegistry
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
import org.bukkit.persistence.PersistentDataContainer
|
||||||
|
import org.bukkit.persistence.PersistentDataType
|
||||||
|
|
||||||
|
class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFactoryProxy {
|
||||||
|
private val registry: CraftPersistentDataTypeRegistry
|
||||||
|
|
||||||
|
init {
|
||||||
|
/*
|
||||||
|
Can't grab actual instance since it's in CraftMetaItem (which is package-private)
|
||||||
|
And getting it would mean more janky reflection
|
||||||
|
*/
|
||||||
|
val item = CraftItemStack.asCraftCopy(ItemStack(Material.STONE))
|
||||||
|
val pdc = item.itemMeta!!.persistentDataContainer
|
||||||
|
this.registry = CraftPersistentDataContainer::class.java.getDeclaredField("registry")
|
||||||
|
.apply { isAccessible = true }.get(pdc) as CraftPersistentDataTypeRegistry
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun adapt(pdc: PersistentDataContainer): ExtendedPersistentDataContainer {
|
||||||
|
return when (pdc) {
|
||||||
|
is CraftPersistentDataContainer -> EcoPersistentDataContainer(pdc)
|
||||||
|
else -> throw IllegalArgumentException("Custom PDC instance ims not supported!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun newPdc(): PersistentDataContainer {
|
||||||
|
return CraftPersistentDataContainer(registry)
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class EcoPersistentDataContainer(
|
||||||
|
private val handle: CraftPersistentDataContainer
|
||||||
|
) : ExtendedPersistentDataContainer {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
private val customDataTags: MutableMap<String, Tag> =
|
||||||
|
CraftPersistentDataContainer::class.java.getDeclaredField("customDataTags")
|
||||||
|
.apply { isAccessible = true }.get(handle) as MutableMap<String, Tag>
|
||||||
|
|
||||||
|
override fun <T : Any, Z : Any> set(key: String, dataType: PersistentDataType<T, Z>, value: Z) {
|
||||||
|
customDataTags[key] =
|
||||||
|
registry.wrap(dataType.primitiveType, dataType.toPrimitive(value, handle.adapterContext))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <T : Any, Z : Any> has(key: String, dataType: PersistentDataType<T, Z>): Boolean {
|
||||||
|
val value = customDataTags[key] ?: return false
|
||||||
|
return registry.isInstanceOf(dataType.primitiveType, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <T : Any, Z : Any> get(key: String, dataType: PersistentDataType<T, Z>): Z? {
|
||||||
|
val value = customDataTags[key] ?: return null
|
||||||
|
return dataType.fromPrimitive(registry.extract(dataType.primitiveType, value), handle.adapterContext)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <T : Any, Z : Any> getOrDefault(
|
||||||
|
key: String,
|
||||||
|
dataType: PersistentDataType<T, Z>,
|
||||||
|
defaultValue: Z
|
||||||
|
): Z {
|
||||||
|
return get(key, dataType) ?: defaultValue
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun remove(key: String) {
|
||||||
|
customDataTags.remove(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getAllKeys(): MutableSet<String> {
|
||||||
|
return customDataTags.keys
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getBase(): PersistentDataContainer {
|
||||||
|
return handle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_19_R2
|
||||||
|
|
||||||
|
import com.willfp.eco.core.fast.FastItemStack
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.common.item.EcoFastItemStack
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
|
||||||
|
class FastItemStackFactory : FastItemStackFactoryProxy {
|
||||||
|
override fun create(itemStack: ItemStack): FastItemStack {
|
||||||
|
return EcoFastItemStack(itemStack)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_19_R2
|
||||||
|
|
||||||
|
import com.willfp.eco.core.display.Display
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.MiniMessageTranslatorProxy
|
||||||
|
import com.willfp.eco.util.toLegacy
|
||||||
|
import net.kyori.adventure.text.minimessage.MiniMessage
|
||||||
|
|
||||||
|
class MiniMessageTranslator : MiniMessageTranslatorProxy {
|
||||||
|
override fun format(message: String): String {
|
||||||
|
var mut = message
|
||||||
|
|
||||||
|
val startsWithPrefix = mut.startsWith(Display.PREFIX)
|
||||||
|
if (startsWithPrefix) {
|
||||||
|
mut = mut.substring(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
mut = mut.replace('§', '&')
|
||||||
|
|
||||||
|
val miniMessage = runCatching {
|
||||||
|
MiniMessage.miniMessage().deserialize(
|
||||||
|
mut
|
||||||
|
).toLegacy()
|
||||||
|
}.getOrNull() ?: mut
|
||||||
|
|
||||||
|
mut = if (startsWithPrefix) {
|
||||||
|
Display.PREFIX + miniMessage
|
||||||
|
} else {
|
||||||
|
miniMessage
|
||||||
|
}
|
||||||
|
|
||||||
|
return mut
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_19_R2
|
||||||
|
|
||||||
|
import com.willfp.eco.core.items.TestableItem
|
||||||
|
import com.willfp.eco.core.recipe.parts.EmptyTestableItem
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.SNBTConverterProxy
|
||||||
|
import net.minecraft.nbt.CompoundTag
|
||||||
|
import net.minecraft.nbt.SnbtPrinterTagVisitor
|
||||||
|
import net.minecraft.nbt.TagParser
|
||||||
|
import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftItemStack
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
|
||||||
|
class SNBTConverter : SNBTConverterProxy {
|
||||||
|
override fun fromSNBT(snbt: String): ItemStack? {
|
||||||
|
val nbt = runCatching { TagParser.parseTag(snbt) }.getOrNull() ?: return null
|
||||||
|
val nms = net.minecraft.world.item.ItemStack.of(nbt)
|
||||||
|
return CraftItemStack.asBukkitCopy(nms)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toSNBT(itemStack: ItemStack): String {
|
||||||
|
val nms = CraftItemStack.asNMSCopy(itemStack)
|
||||||
|
return SnbtPrinterTagVisitor().visit(nms.save(CompoundTag()))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun makeSNBTTestable(snbt: String): TestableItem {
|
||||||
|
val nbt = runCatching { TagParser.parseTag(snbt) }.getOrNull() ?: return EmptyTestableItem()
|
||||||
|
val nms = net.minecraft.world.item.ItemStack.of(nbt)
|
||||||
|
if (nms == net.minecraft.world.item.ItemStack.EMPTY) {
|
||||||
|
return EmptyTestableItem()
|
||||||
|
}
|
||||||
|
|
||||||
|
nbt.remove("Count")
|
||||||
|
return SNBTTestableItem(CraftItemStack.asBukkitCopy(nms), nbt)
|
||||||
|
}
|
||||||
|
|
||||||
|
class SNBTTestableItem(
|
||||||
|
private val item: ItemStack,
|
||||||
|
private val tag: CompoundTag
|
||||||
|
) : TestableItem {
|
||||||
|
override fun matches(itemStack: ItemStack?): Boolean {
|
||||||
|
if (itemStack == null) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val nms = CraftItemStack.asNMSCopy(itemStack)
|
||||||
|
val nmsTag = nms.save(CompoundTag())
|
||||||
|
nmsTag.remove("Count")
|
||||||
|
return tag.copy().merge(nmsTag) == nmsTag
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItem(): ItemStack = item
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_19_R2
|
||||||
|
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.SkullProxy
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.common.texture
|
||||||
|
import org.bukkit.inventory.meta.SkullMeta
|
||||||
|
|
||||||
|
class Skull : SkullProxy {
|
||||||
|
override fun setSkullTexture(
|
||||||
|
meta: SkullMeta,
|
||||||
|
base64: String
|
||||||
|
) {
|
||||||
|
meta.texture = base64
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getSkullTexture(
|
||||||
|
meta: SkullMeta
|
||||||
|
): String? = meta.texture
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_19_R2
|
||||||
|
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.TPSProxy
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.craftbukkit.v1_19_R2.CraftServer
|
||||||
|
|
||||||
|
class TPS : TPSProxy {
|
||||||
|
override fun getTPS(): Double {
|
||||||
|
return (Bukkit.getServer() as CraftServer).handle.server.recentTps[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_19_R2
|
||||||
|
|
||||||
|
import com.willfp.eco.core.display.Display
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.VillagerTradeProxy
|
||||||
|
import net.minecraft.nbt.CompoundTag
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
|
import net.minecraft.world.item.trading.MerchantOffer
|
||||||
|
import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftItemStack
|
||||||
|
import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftMerchantRecipe
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.inventory.MerchantRecipe
|
||||||
|
import java.lang.reflect.Field
|
||||||
|
|
||||||
|
class VillagerTrade : VillagerTradeProxy {
|
||||||
|
private val handle: Field = CraftMerchantRecipe::class.java.getDeclaredField("handle")
|
||||||
|
|
||||||
|
override fun displayTrade(
|
||||||
|
recipe: MerchantRecipe,
|
||||||
|
player: Player
|
||||||
|
): MerchantRecipe {
|
||||||
|
recipe as CraftMerchantRecipe
|
||||||
|
|
||||||
|
val nbt = getHandle(recipe).createTag()
|
||||||
|
for (tag in arrayOf("buy", "buyB", "sell")) {
|
||||||
|
val nms = ItemStack.of(nbt.getCompound(tag))
|
||||||
|
val displayed = Display.display(CraftItemStack.asBukkitCopy(nms), player)
|
||||||
|
val itemNBT = CraftItemStack.asNMSCopy(displayed).save(CompoundTag())
|
||||||
|
nbt.put(tag, itemNBT)
|
||||||
|
}
|
||||||
|
|
||||||
|
return CraftMerchantRecipe(MerchantOffer(nbt))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getHandle(recipe: CraftMerchantRecipe): MerchantOffer {
|
||||||
|
return handle[recipe] as MerchantOffer
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
handle.isAccessible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,7 +31,8 @@ dependencies {
|
|||||||
compileOnly('com.github.TownyAdvanced:Towny:0.97.2.6') {
|
compileOnly('com.github.TownyAdvanced:Towny:0.97.2.6') {
|
||||||
exclude group: 'com.zaxxer', module: 'HikariCP'
|
exclude group: 'com.zaxxer', module: 'HikariCP'
|
||||||
}
|
}
|
||||||
compileOnly 'com.github.angeschossen:LandsAPI:5.15.2'
|
compileOnly 'com.github.angeschossen:LandsAPI:6.26.7'
|
||||||
|
compileOnly 'com.github.angeschossen:PluginFrameworkAPI:1.0.0'
|
||||||
compileOnly 'fr.neatmonster:nocheatplus:3.16.1-SNAPSHOT'
|
compileOnly 'fr.neatmonster:nocheatplus:3.16.1-SNAPSHOT'
|
||||||
compileOnly 'com.github.jiangdashao:matrix-api-repo:317d4635fd'
|
compileOnly 'com.github.jiangdashao:matrix-api-repo:317d4635fd'
|
||||||
compileOnly 'com.gmail.nossr50.mcMMO:mcMMO:2.1.202'
|
compileOnly 'com.gmail.nossr50.mcMMO:mcMMO:2.1.202'
|
||||||
@@ -50,10 +51,12 @@ dependencies {
|
|||||||
compileOnly 'com.github.Gypopo:EconomyShopGUI-API:1.1.0'
|
compileOnly 'com.github.Gypopo:EconomyShopGUI-API:1.1.0'
|
||||||
compileOnly 'com.github.N0RSKA:ScytherAPI:55a'
|
compileOnly 'com.github.N0RSKA:ScytherAPI:55a'
|
||||||
compileOnly 'com.ticxo.modelengine:api:R3.0.1'
|
compileOnly 'com.ticxo.modelengine:api:R3.0.1'
|
||||||
|
compileOnly 'me.TechsCode:UltraEconomyAPI:1.0.0'
|
||||||
|
compileOnly 'com.github.Ssomar-Developement:SCore:3.4.7'
|
||||||
|
|
||||||
// MythicMobs
|
// MythicMobs
|
||||||
compileOnly 'io.lumine:Mythic:5.0.1'
|
compileOnly 'io.lumine:Mythic:5.2.1'
|
||||||
compileOnly 'io.lumine:LumineUtils:1.16.1-SNAPSHOT'
|
compileOnly 'io.lumine:LumineUtils:1.19-SNAPSHOT'
|
||||||
|
|
||||||
// CombatLogX V10 + NewbieHelper Expansion
|
// CombatLogX V10 + NewbieHelper Expansion
|
||||||
compileOnly 'com.SirBlobman.combatlogx:CombatLogX-API:10.0.0.0-SNAPSHOT'
|
compileOnly 'com.SirBlobman.combatlogx:CombatLogX-API:10.0.0.0-SNAPSHOT'
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import com.willfp.eco.core.Eco
|
|||||||
import com.willfp.eco.core.EcoPlugin
|
import com.willfp.eco.core.EcoPlugin
|
||||||
import com.willfp.eco.core.PluginLike
|
import com.willfp.eco.core.PluginLike
|
||||||
import com.willfp.eco.core.PluginProps
|
import com.willfp.eco.core.PluginProps
|
||||||
|
import com.willfp.eco.core.command.CommandBase
|
||||||
|
import com.willfp.eco.core.command.impl.PluginCommand
|
||||||
import com.willfp.eco.core.config.ConfigType
|
import com.willfp.eco.core.config.ConfigType
|
||||||
import com.willfp.eco.core.config.interfaces.Config
|
import com.willfp.eco.core.config.interfaces.Config
|
||||||
import com.willfp.eco.core.data.keys.PersistentDataKey
|
import com.willfp.eco.core.data.keys.PersistentDataKey
|
||||||
@@ -13,11 +15,9 @@ import com.willfp.eco.core.gui.slot.functional.SlotProvider
|
|||||||
import com.willfp.eco.core.items.Items
|
import com.willfp.eco.core.items.Items
|
||||||
import com.willfp.eco.core.math.MathContext
|
import com.willfp.eco.core.math.MathContext
|
||||||
import com.willfp.eco.internal.EcoPropsParser
|
import com.willfp.eco.internal.EcoPropsParser
|
||||||
import com.willfp.eco.internal.config.EcoConfigHandler
|
import com.willfp.eco.internal.command.EcoPluginCommand
|
||||||
import com.willfp.eco.internal.config.EcoConfigSection
|
import com.willfp.eco.internal.command.EcoSubcommand
|
||||||
import com.willfp.eco.internal.config.EcoLoadableConfig
|
import com.willfp.eco.internal.config.*
|
||||||
import com.willfp.eco.internal.config.EcoUpdatableConfig
|
|
||||||
import com.willfp.eco.internal.config.toMap
|
|
||||||
import com.willfp.eco.internal.drops.EcoDropQueue
|
import com.willfp.eco.internal.drops.EcoDropQueue
|
||||||
import com.willfp.eco.internal.drops.EcoFastCollatedDropQueue
|
import com.willfp.eco.internal.drops.EcoFastCollatedDropQueue
|
||||||
import com.willfp.eco.internal.events.EcoEventManager
|
import com.willfp.eco.internal.events.EcoEventManager
|
||||||
@@ -42,6 +42,7 @@ import com.willfp.eco.internal.spigot.data.ProfileHandler
|
|||||||
import com.willfp.eco.internal.spigot.data.storage.HandlerType
|
import com.willfp.eco.internal.spigot.data.storage.HandlerType
|
||||||
import com.willfp.eco.internal.spigot.integrations.bstats.MetricHandler
|
import com.willfp.eco.internal.spigot.integrations.bstats.MetricHandler
|
||||||
import com.willfp.eco.internal.spigot.math.evaluateExpression
|
import com.willfp.eco.internal.spigot.math.evaluateExpression
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.BukkitCommandsProxy
|
||||||
import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
|
import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
|
||||||
import com.willfp.eco.internal.spigot.proxy.DummyEntityFactoryProxy
|
import com.willfp.eco.internal.spigot.proxy.DummyEntityFactoryProxy
|
||||||
import com.willfp.eco.internal.spigot.proxy.EntityControllerFactoryProxy
|
import com.willfp.eco.internal.spigot.proxy.EntityControllerFactoryProxy
|
||||||
@@ -50,10 +51,10 @@ import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy
|
|||||||
import com.willfp.eco.internal.spigot.proxy.MiniMessageTranslatorProxy
|
import com.willfp.eco.internal.spigot.proxy.MiniMessageTranslatorProxy
|
||||||
import com.willfp.eco.internal.spigot.proxy.SNBTConverterProxy
|
import com.willfp.eco.internal.spigot.proxy.SNBTConverterProxy
|
||||||
import com.willfp.eco.internal.spigot.proxy.SkullProxy
|
import com.willfp.eco.internal.spigot.proxy.SkullProxy
|
||||||
import com.willfp.eco.internal.spigot.proxy.SyncCommandsProxy
|
|
||||||
import com.willfp.eco.internal.spigot.proxy.TPSProxy
|
import com.willfp.eco.internal.spigot.proxy.TPSProxy
|
||||||
import org.bukkit.Location
|
import org.bukkit.Location
|
||||||
import org.bukkit.NamespacedKey
|
import org.bukkit.NamespacedKey
|
||||||
|
import org.bukkit.command.CommandMap
|
||||||
import org.bukkit.configuration.ConfigurationSection
|
import org.bukkit.configuration.ConfigurationSection
|
||||||
import org.bukkit.entity.Entity
|
import org.bukkit.entity.Entity
|
||||||
import org.bukkit.entity.Mob
|
import org.bukkit.entity.Mob
|
||||||
@@ -62,7 +63,7 @@ import org.bukkit.inventory.ItemStack
|
|||||||
import org.bukkit.inventory.meta.SkullMeta
|
import org.bukkit.inventory.meta.SkullMeta
|
||||||
import org.bukkit.persistence.PersistentDataContainer
|
import org.bukkit.persistence.PersistentDataContainer
|
||||||
import java.net.URLClassLoader
|
import java.net.URLClassLoader
|
||||||
import java.util.UUID
|
import java.util.*
|
||||||
|
|
||||||
private val loadedEcoPlugins = mutableMapOf<String, EcoPlugin>()
|
private val loadedEcoPlugins = mutableMapOf<String, EcoPlugin>()
|
||||||
|
|
||||||
@@ -166,7 +167,36 @@ class EcoImpl : EcoSpigotPlugin(), Eco {
|
|||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createDropQueue(player: Player) = if (this.configYml.getBool("use-fast-collated-drops"))
|
override fun createPluginCommand(
|
||||||
|
parentDelegate: CommandBase,
|
||||||
|
plugin: EcoPlugin,
|
||||||
|
name: String,
|
||||||
|
permission: String,
|
||||||
|
playersOnly: Boolean
|
||||||
|
) = EcoPluginCommand(
|
||||||
|
parentDelegate,
|
||||||
|
plugin,
|
||||||
|
name,
|
||||||
|
permission,
|
||||||
|
playersOnly
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun createSubcommand(
|
||||||
|
parentDelegate: CommandBase,
|
||||||
|
plugin: EcoPlugin,
|
||||||
|
name: String,
|
||||||
|
permission: String,
|
||||||
|
playersOnly: Boolean
|
||||||
|
) = EcoSubcommand(
|
||||||
|
parentDelegate,
|
||||||
|
plugin,
|
||||||
|
name,
|
||||||
|
permission,
|
||||||
|
playersOnly
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun createDropQueue(player: Player) =
|
||||||
|
if (this.configYml.getBool("use-fast-collated-drops"))
|
||||||
EcoFastCollatedDropQueue(player) else EcoDropQueue(player)
|
EcoFastCollatedDropQueue(player) else EcoDropQueue(player)
|
||||||
|
|
||||||
override fun getRegisteredPersistentDataKeys() =
|
override fun getRegisteredPersistentDataKeys() =
|
||||||
@@ -285,5 +315,11 @@ class EcoImpl : EcoSpigotPlugin(), Eco {
|
|||||||
player.renderedInventory?.menu
|
player.renderedInventory?.menu
|
||||||
|
|
||||||
override fun syncCommands() =
|
override fun syncCommands() =
|
||||||
this.getProxy(SyncCommandsProxy::class.java).syncCommands()
|
this.getProxy(BukkitCommandsProxy::class.java).syncCommands()
|
||||||
|
|
||||||
|
override fun getCommandMap(): CommandMap =
|
||||||
|
this.getProxy(BukkitCommandsProxy::class.java).getCommandMap()
|
||||||
|
|
||||||
|
override fun unregisterCommand(command: PluginCommand) =
|
||||||
|
this.getProxy(BukkitCommandsProxy::class.java).unregisterCommand(command)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ import com.willfp.eco.internal.spigot.integrations.hologram.HologramHolographicD
|
|||||||
import com.willfp.eco.internal.spigot.integrations.mcmmo.McmmoIntegrationImpl
|
import com.willfp.eco.internal.spigot.integrations.mcmmo.McmmoIntegrationImpl
|
||||||
import com.willfp.eco.internal.spigot.integrations.multiverseinventories.MultiverseInventoriesIntegration
|
import com.willfp.eco.internal.spigot.integrations.multiverseinventories.MultiverseInventoriesIntegration
|
||||||
import com.willfp.eco.internal.spigot.integrations.placeholder.PlaceholderIntegrationPAPI
|
import com.willfp.eco.internal.spigot.integrations.placeholder.PlaceholderIntegrationPAPI
|
||||||
|
import com.willfp.eco.internal.spigot.integrations.price.PriceFactoryUltraEconomy
|
||||||
import com.willfp.eco.internal.spigot.integrations.shop.ShopDeluxeSellwands
|
import com.willfp.eco.internal.spigot.integrations.shop.ShopDeluxeSellwands
|
||||||
import com.willfp.eco.internal.spigot.integrations.shop.ShopEconomyShopGUI
|
import com.willfp.eco.internal.spigot.integrations.shop.ShopEconomyShopGUI
|
||||||
import com.willfp.eco.internal.spigot.integrations.shop.ShopShopGuiPlus
|
import com.willfp.eco.internal.spigot.integrations.shop.ShopShopGuiPlus
|
||||||
@@ -126,6 +127,7 @@ import com.willfp.eco.internal.spigot.recipes.listeners.ComplexInComplex
|
|||||||
import com.willfp.eco.internal.spigot.recipes.listeners.ComplexInVanilla
|
import com.willfp.eco.internal.spigot.recipes.listeners.ComplexInVanilla
|
||||||
import com.willfp.eco.internal.spigot.recipes.stackhandlers.ShapedCraftingRecipeStackHandler
|
import com.willfp.eco.internal.spigot.recipes.stackhandlers.ShapedCraftingRecipeStackHandler
|
||||||
import com.willfp.eco.internal.spigot.recipes.stackhandlers.ShapelessCraftingRecipeStackHandler
|
import com.willfp.eco.internal.spigot.recipes.stackhandlers.ShapelessCraftingRecipeStackHandler
|
||||||
|
import me.TechsCode.UltraEconomy.UltraEconomy
|
||||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences
|
import net.kyori.adventure.platform.bukkit.BukkitAudiences
|
||||||
import net.milkbowl.vault.economy.Economy
|
import net.milkbowl.vault.economy.Economy
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
@@ -263,7 +265,6 @@ abstract class EcoSpigotPlugin : EcoPlugin() {
|
|||||||
IntegrationLoader("IridiumSkyblock") { AntigriefManager.register(AntigriefIridiumSkyblock()) },
|
IntegrationLoader("IridiumSkyblock") { AntigriefManager.register(AntigriefIridiumSkyblock()) },
|
||||||
IntegrationLoader("DeluxeCombat") { AntigriefManager.register(AntigriefDeluxeCombat()) },
|
IntegrationLoader("DeluxeCombat") { AntigriefManager.register(AntigriefDeluxeCombat()) },
|
||||||
IntegrationLoader("SuperiorSkyblock2") { AntigriefManager.register(AntigriefSuperiorSkyblock2()) },
|
IntegrationLoader("SuperiorSkyblock2") { AntigriefManager.register(AntigriefSuperiorSkyblock2()) },
|
||||||
IntegrationLoader("FabledSkyBlock") { AntigriefManager.register(AntigriefFabledSkyBlock()) },
|
|
||||||
IntegrationLoader("BentoBox") { AntigriefManager.register(AntigriefBentoBox()) },
|
IntegrationLoader("BentoBox") { AntigriefManager.register(AntigriefBentoBox()) },
|
||||||
IntegrationLoader("WorldGuard") { AntigriefManager.register(AntigriefWorldGuard()) },
|
IntegrationLoader("WorldGuard") { AntigriefManager.register(AntigriefWorldGuard()) },
|
||||||
IntegrationLoader("GriefPrevention") { AntigriefManager.register(AntigriefGriefPrevention()) },
|
IntegrationLoader("GriefPrevention") { AntigriefManager.register(AntigriefGriefPrevention()) },
|
||||||
@@ -285,6 +286,7 @@ abstract class EcoSpigotPlugin : EcoPlugin() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
IntegrationLoader("PvPManager") { AntigriefManager.register(AntigriefPvPManager()) },
|
IntegrationLoader("PvPManager") { AntigriefManager.register(AntigriefPvPManager()) },
|
||||||
|
IntegrationLoader("FabledSkyblock") { AntigriefManager.register(AntigriefFabledSkyBlock()) },
|
||||||
|
|
||||||
// Anticheat
|
// Anticheat
|
||||||
IntegrationLoader("AAC5") { AnticheatManager.register(AnticheatAAC()) },
|
IntegrationLoader("AAC5") { AnticheatManager.register(AnticheatAAC()) },
|
||||||
@@ -333,6 +335,13 @@ abstract class EcoSpigotPlugin : EcoPlugin() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Price
|
||||||
|
IntegrationLoader("UltraEconomy") {
|
||||||
|
for (currency in UltraEconomy.getAPI().currencies) {
|
||||||
|
Prices.registerPriceFactory(PriceFactoryUltraEconomy(currency))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// Placeholder
|
// Placeholder
|
||||||
IntegrationLoader("PlaceholderAPI") { PlaceholderManager.addIntegration(PlaceholderIntegrationPAPI()) },
|
IntegrationLoader("PlaceholderAPI") { PlaceholderManager.addIntegration(PlaceholderIntegrationPAPI()) },
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import org.bukkit.event.Listener
|
|||||||
import org.bukkit.event.inventory.ClickType
|
import org.bukkit.event.inventory.ClickType
|
||||||
import org.bukkit.event.inventory.InventoryClickEvent
|
import org.bukkit.event.inventory.InventoryClickEvent
|
||||||
import org.bukkit.event.inventory.InventoryCloseEvent
|
import org.bukkit.event.inventory.InventoryCloseEvent
|
||||||
|
import org.bukkit.event.inventory.InventoryDragEvent
|
||||||
import org.bukkit.event.player.PlayerItemHeldEvent
|
import org.bukkit.event.player.PlayerItemHeldEvent
|
||||||
import org.bukkit.inventory.PlayerInventory
|
import org.bukkit.inventory.PlayerInventory
|
||||||
|
|
||||||
@@ -73,6 +74,33 @@ class GUIListener(private val plugin: EcoPlugin) : Listener {
|
|||||||
menu.getSlot(row, column, player).handle(player, event, menu)
|
menu.getSlot(row, column, player).handle(player, event, menu)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EventHandler(
|
||||||
|
priority = EventPriority.HIGH
|
||||||
|
)
|
||||||
|
fun handleSlotClick(event: InventoryDragEvent) {
|
||||||
|
val rendered = event.view.topInventory.asRenderedInventory() ?: return
|
||||||
|
|
||||||
|
val player = event.whoClicked as? Player ?: return
|
||||||
|
|
||||||
|
val menu = rendered.menu
|
||||||
|
|
||||||
|
val slots = event.inventorySlots
|
||||||
|
|
||||||
|
for (slotID in slots) {
|
||||||
|
val (row, column) = MenuUtils.convertSlotToRowColumn(slotID, menu.columns)
|
||||||
|
|
||||||
|
val slot = menu.getSlot(row, column, player)
|
||||||
|
|
||||||
|
if (slot.isCaptive(player, menu)) {
|
||||||
|
if (!slot.isAllowedCaptive(player, menu, event.oldCursor)) {
|
||||||
|
event.isCancelled = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
event.isCancelled = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@EventHandler(
|
@EventHandler(
|
||||||
priority = EventPriority.HIGH
|
priority = EventPriority.HIGH
|
||||||
)
|
)
|
||||||
@@ -95,7 +123,11 @@ class GUIListener(private val plugin: EcoPlugin) : Listener {
|
|||||||
|
|
||||||
val slot = menu.getSlot(row, column, player)
|
val slot = menu.getSlot(row, column, player)
|
||||||
|
|
||||||
if (!slot.isCaptive(player, menu)) {
|
if (slot.isCaptive(player, menu)) {
|
||||||
|
if (!slot.isAllowedCaptive(player, menu, event.currentItem)) {
|
||||||
|
event.isCancelled = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
event.isCancelled = true
|
event.isCancelled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,6 +147,12 @@ class GUIListener(private val plugin: EcoPlugin) : Listener {
|
|||||||
player.renderActiveMenu()
|
player.renderActiveMenu()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
fun forceRender(event: InventoryDragEvent) {
|
||||||
|
val player = event.whoClicked as? Player ?: return
|
||||||
|
player.renderActiveMenu()
|
||||||
|
}
|
||||||
|
|
||||||
@EventHandler(
|
@EventHandler(
|
||||||
priority = EventPriority.HIGHEST
|
priority = EventPriority.HIGHEST
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import org.bukkit.entity.Monster
|
|||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
class AntigriefFabledSkyBlock : AntigriefIntegration {
|
class AntigriefFabledSkyBlock : AntigriefIntegration {
|
||||||
|
|
||||||
override fun getPluginName(): String {
|
override fun getPluginName(): String {
|
||||||
return "FabledSkyBlock"
|
return "FabledSkyBlock"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ package com.willfp.eco.internal.spigot.integrations.antigrief
|
|||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin
|
import com.willfp.eco.core.EcoPlugin
|
||||||
import com.willfp.eco.core.integrations.antigrief.AntigriefIntegration
|
import com.willfp.eco.core.integrations.antigrief.AntigriefIntegration
|
||||||
|
import me.angeschossen.lands.api.LandsIntegration
|
||||||
import me.angeschossen.lands.api.flags.Flags
|
import me.angeschossen.lands.api.flags.Flags
|
||||||
import me.angeschossen.lands.api.integration.LandsIntegration
|
|
||||||
import org.bukkit.Location
|
import org.bukkit.Location
|
||||||
import org.bukkit.block.Block
|
import org.bukkit.block.Block
|
||||||
import org.bukkit.entity.Animals
|
import org.bukkit.entity.Animals
|
||||||
@@ -12,12 +12,12 @@ import org.bukkit.entity.Monster
|
|||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
class AntigriefLands(private val plugin: EcoPlugin) : AntigriefIntegration {
|
class AntigriefLands(private val plugin: EcoPlugin) : AntigriefIntegration {
|
||||||
private val landsIntegration = LandsIntegration(this.plugin)
|
private val landsIntegration = LandsIntegration.of(this.plugin)
|
||||||
override fun canBreakBlock(
|
override fun canBreakBlock(
|
||||||
player: Player,
|
player: Player,
|
||||||
block: Block
|
block: Block
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val area = landsIntegration.getAreaByLoc(block.location) ?: return true
|
val area = landsIntegration.getArea(block.location) ?: return true
|
||||||
return area.hasFlag(player, Flags.BLOCK_BREAK, false)
|
return area.hasFlag(player, Flags.BLOCK_BREAK, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ class AntigriefLands(private val plugin: EcoPlugin) : AntigriefIntegration {
|
|||||||
player: Player,
|
player: Player,
|
||||||
location: Location
|
location: Location
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val area = landsIntegration.getAreaByLoc(location) ?: return true
|
val area = landsIntegration.getArea(location) ?: return true
|
||||||
return area.hasFlag(player, Flags.ATTACK_PLAYER, false) && area.hasFlag(player, Flags.ATTACK_ANIMAL, false)
|
return area.hasFlag(player, Flags.ATTACK_PLAYER, false) && area.hasFlag(player, Flags.ATTACK_ANIMAL, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ class AntigriefLands(private val plugin: EcoPlugin) : AntigriefIntegration {
|
|||||||
player: Player,
|
player: Player,
|
||||||
block: Block
|
block: Block
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val area = landsIntegration.getAreaByLoc(block.location) ?: return true
|
val area = landsIntegration.getArea(block.location) ?: return true
|
||||||
return area.hasFlag(player, Flags.BLOCK_PLACE, false)
|
return area.hasFlag(player, Flags.BLOCK_PLACE, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ class AntigriefLands(private val plugin: EcoPlugin) : AntigriefIntegration {
|
|||||||
victim: LivingEntity
|
victim: LivingEntity
|
||||||
): Boolean {
|
): Boolean {
|
||||||
|
|
||||||
val area = landsIntegration.getAreaByLoc(victim.location) ?: return true
|
val area = landsIntegration.getArea(victim.location) ?: return true
|
||||||
|
|
||||||
return when(victim) {
|
return when(victim) {
|
||||||
is Player -> area.hasFlag(player, Flags.ATTACK_PLAYER, false)
|
is Player -> area.hasFlag(player, Flags.ATTACK_PLAYER, false)
|
||||||
@@ -53,7 +53,7 @@ class AntigriefLands(private val plugin: EcoPlugin) : AntigriefIntegration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun canPickupItem(player: Player, location: Location): Boolean {
|
override fun canPickupItem(player: Player, location: Location): Boolean {
|
||||||
val area = landsIntegration.getAreaByLoc(location) ?: return true
|
val area = landsIntegration.getArea(location) ?: return true
|
||||||
return area.hasFlag(player, Flags.ITEM_PICKUP, false)
|
return area.hasFlag(player, Flags.ITEM_PICKUP, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.willfp.eco.internal.spigot.integrations.antigrief
|
package com.willfp.eco.internal.spigot.integrations.antigrief
|
||||||
|
|
||||||
import com.willfp.eco.core.integrations.antigrief.AntigriefIntegration
|
import com.willfp.eco.core.integrations.antigrief.AntigriefIntegration
|
||||||
|
import me.NoChance.PvPManager.PvPlayer
|
||||||
import org.bukkit.Location
|
import org.bukkit.Location
|
||||||
import org.bukkit.block.Block
|
import org.bukkit.block.Block
|
||||||
import org.bukkit.entity.LivingEntity
|
import org.bukkit.entity.LivingEntity
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
import me.NoChance.PvPManager.PvPlayer
|
|
||||||
|
|
||||||
class AntigriefPvPManager: AntigriefIntegration {
|
class AntigriefPvPManager: AntigriefIntegration {
|
||||||
override fun getPluginName(): String {
|
override fun getPluginName(): String {
|
||||||
@@ -27,7 +27,7 @@ class AntigriefPvPManager: AntigriefIntegration {
|
|||||||
override fun canInjure(player: Player, victim: LivingEntity): Boolean {
|
override fun canInjure(player: Player, victim: LivingEntity): Boolean {
|
||||||
return when(victim) {
|
return when(victim) {
|
||||||
is Player -> {
|
is Player -> {
|
||||||
(PvPlayer.get(victim).isInCombat())}
|
(PvPlayer.get(victim).isInCombat)}
|
||||||
else -> true
|
else -> true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import java.util.logging.Level
|
|||||||
import java.util.zip.GZIPOutputStream
|
import java.util.zip.GZIPOutputStream
|
||||||
import javax.net.ssl.HttpsURLConnection
|
import javax.net.ssl.HttpsURLConnection
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
class Metrics(private val plugin: EcoPlugin) {
|
class Metrics(private val plugin: EcoPlugin) {
|
||||||
private val metricsBase: MetricsBase
|
private val metricsBase: MetricsBase
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class CustomEntitiesMythicMobs : CustomEntitiesIntegration {
|
|||||||
CustomEntity(
|
CustomEntity(
|
||||||
key,
|
key,
|
||||||
{
|
{
|
||||||
val entityId = api.getMythicMobInstance(it)?.type?.entityType ?: return@CustomEntity false
|
val entityId = api.getMythicMobInstance(it)?.type?.entityType?.name ?: return@CustomEntity false
|
||||||
entityId.equals(id, ignoreCase = true)
|
entityId.equals(id, ignoreCase = true)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user