Compare commits

..

60 Commits

Author SHA1 Message Date
Auxilor
cb28726bc3 Cleaned up Multiverse-Inventories integration 2021-10-12 12:04:52 +01:00
Auxilor
c0c20d63bb Merge remote-tracking branch 'origin/master' into develop 2021-10-12 11:59:26 +01:00
Will FP
3b11610c45 Merge pull request #44
Multiverse-Inventories integration
2021-10-12 11:58:41 +01:00
Auxilor
232048022e Added extra config constructors 2021-10-12 11:51:22 +01:00
Auxilor
9abfe0ab01 Updated to 6.11.0 2021-10-12 11:36:07 +01:00
Auxilor
e7ac05278c Added lots of display frame options 2021-10-12 11:31:02 +01:00
Auxilor
85ba40c279 Added PluginLike, allowing extensions to have their own configs 2021-10-12 11:17:58 +01:00
_OfTeN_
1acf86492e Added Multiverse-Inventories integration (additional ArmorChangeEvent call for all effect to reapply for new players inventory. 2021-10-12 11:09:09 +03:00
Auxilor
4609d38389 Updated to 6.10.1 2021-10-08 10:50:57 +01:00
Auxilor
2d6836cc93 Moved frames to only affect player inventories 2021-10-08 10:50:47 +01:00
Auxilor
8e21617345 Finished up ChatComponent 2021-10-07 20:50:15 +01:00
Auxilor
2f99a17d02 TODO: Finish Components 2021-10-07 16:16:07 +01:00
Auxilor
34edf1d7b4 Switched mapChildrenDeep to mapChildren 2021-10-07 16:01:49 +01:00
Auxilor
be85ba5706 Fixed Stack Overflow 2021-10-07 15:44:59 +01:00
Auxilor
b817b00ca4 Updated ChatComponent to include siblings 2021-10-07 15:37:35 +01:00
Auxilor
ee02528abc Downgraded Reflections 2021-10-07 15:07:24 +01:00
Auxilor
794948c8f9 Altered Reflections constructor (again) 2021-10-07 15:01:35 +01:00
Auxilor
7c70dec2e7 Added AntigriefManager#unregister 2021-10-07 15:00:54 +01:00
Auxilor
d1f20b7111 Updated Reflections constructor 2021-10-07 14:49:52 +01:00
Auxilor
595751a094 Fixed build warnings 2021-10-07 14:45:42 +01:00
Auxilor
8231afdcbf Fixed dependency-related issues (Reflections) 2021-10-07 14:39:44 +01:00
Auxilor
4f55d66096 Updated to 6.10.0 2021-10-07 14:36:03 +01:00
Auxilor
d350febbdc Minor change 2021-10-07 14:35:52 +01:00
Auxilor
78755b0e9a (Hopefully) massively optimized display (PacketWindowItems) with DisplayFrame.kt 2021-10-07 14:34:40 +01:00
Auxilor
63d7bdab6b Re-Added Head Database integration 2021-10-07 13:58:42 +01:00
Auxilor
344032b7e3 Added ItemProvider 2021-10-07 13:45:45 +01:00
Auxilor
3ae5c8a72c Moved ArmorEquipEvent code to kotlin, finally 2021-10-07 13:13:33 +01:00
Auxilor
e4f2bc2e39 Finally recoded remaining java in NMS to kotlin 2021-10-07 13:03:19 +01:00
Auxilor
90ba0a0391 Updated dependencies 2021-10-07 12:50:53 +01:00
Auxilor
801a3cd4f9 Merge remote-tracking branch 'origin/master' 2021-10-07 12:48:44 +01:00
Will FP
ce9cada75a Merge pull request #35
Bump ProtocolLib from 4.6.0-SNAPSHOT to 4.7.1-SNAPSHOT
2021-10-07 12:48:24 +01:00
Will FP
ae551dd0f7 Merge pull request #36
Bump junit-jupiter-engine from 5.3.1 to 5.8.1
2021-10-07 12:47:38 +01:00
Will FP
1b3dd53fb8 Merge pull request #37
Bump reflections from 0.9.12 to 0.10.1
2021-10-07 12:47:29 +01:00
Will FP
dda4224e6e Merge pull request #38
Bump lombok from 1.18.20 to 1.18.22
2021-10-07 12:47:19 +01:00
dependabot[bot]
6e14265655 Bump lombok from 1.18.20 to 1.18.22
Bumps [lombok](https://github.com/projectlombok/lombok) from 1.18.20 to 1.18.22.
- [Release notes](https://github.com/projectlombok/lombok/releases)
- [Changelog](https://github.com/projectlombok/lombok/blob/master/doc/changelog.markdown)
- [Commits](https://github.com/projectlombok/lombok/compare/v1.18.20...v1.18.22)

---
updated-dependencies:
- dependency-name: org.projectlombok:lombok
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-07 11:47:09 +00:00
dependabot[bot]
77fd99d215 Bump reflections from 0.9.12 to 0.10.1
Bumps [reflections](https://github.com/ronmamo/reflections) from 0.9.12 to 0.10.1.
- [Release notes](https://github.com/ronmamo/reflections/releases)
- [Commits](https://github.com/ronmamo/reflections/compare/0.9.12...0.10.1)

---
updated-dependencies:
- dependency-name: org.reflections:reflections
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-07 11:47:01 +00:00
Will FP
cf05efc2ff Merge pull request #26
Bump kotlin-gradle-plugin from 1.5.21 to 1.5.31
2021-10-07 12:46:59 +01:00
dependabot[bot]
0e8c759a4c Bump junit-jupiter-engine from 5.3.1 to 5.8.1
Bumps [junit-jupiter-engine](https://github.com/junit-team/junit5) from 5.3.1 to 5.8.1.
- [Release notes](https://github.com/junit-team/junit5/releases)
- [Commits](https://github.com/junit-team/junit5/compare/r5.3.1...r5.8.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-07 11:46:18 +00:00
Will FP
ba7bfb828b Merge pull request #30
Bump adventure-text-serializer-gson from 4.8.1 to 4.9.2
2021-10-07 12:46:13 +01:00
dependabot[bot]
8dd1239b99 Bump ProtocolLib from 4.6.0-SNAPSHOT to 4.7.1-SNAPSHOT
Bumps ProtocolLib from 4.6.0-SNAPSHOT to 4.7.1-SNAPSHOT.

---
updated-dependencies:
- dependency-name: com.comphenix.protocol:ProtocolLib
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-07 11:46:04 +00:00
Will FP
edada09966 Merge pull request #31
Bump mcMMO from 2.1.157 to 2.1.202
2021-10-07 12:46:01 +01:00
Auxilor
19c300bbf3 Merge remote-tracking branch 'origin/master' 2021-10-07 12:45:45 +01:00
Will FP
4fc9c21034 Merge pull request #32
Bump Towny from 0.97.1.0 to 0.97.2.5
2021-10-07 12:45:20 +01:00
Auxilor
2366dcd293 Merge remote-tracking branch 'origin/master' 2021-10-07 12:44:48 +01:00
Auxilor
054e6a53c0 Fixed dumb Any? constraint 2021-10-07 11:51:42 +01:00
Auxilor
46f590fe3e Recoded PacketChat 2021-10-07 11:50:26 +01:00
dependabot[bot]
b46aaf547f Bump Towny from 0.97.1.0 to 0.97.2.5
Bumps [Towny](https://github.com/TownyAdvanced/Towny) from 0.97.1.0 to 0.97.2.5.
- [Release notes](https://github.com/TownyAdvanced/Towny/releases)
- [Commits](https://github.com/TownyAdvanced/Towny/compare/0.97.1.0...0.97.2.5)

---
updated-dependencies:
- dependency-name: com.github.TownyAdvanced:Towny
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-05 21:23:42 +00:00
dependabot[bot]
0f7125e1c8 Bump mcMMO from 2.1.157 to 2.1.202
Bumps [mcMMO](https://github.com/mcMMO-Dev/mcMMO) from 2.1.157 to 2.1.202.
- [Release notes](https://github.com/mcMMO-Dev/mcMMO/releases)
- [Changelog](https://github.com/mcMMO-Dev/mcMMO/blob/master/Changelog.txt)
- [Commits](https://github.com/mcMMO-Dev/mcMMO/commits)

---
updated-dependencies:
- dependency-name: com.gmail.nossr50.mcMMO:mcMMO
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-05 21:20:47 +00:00
dependabot[bot]
6cb99819f3 Bump adventure-text-serializer-gson from 4.8.1 to 4.9.2
Bumps [adventure-text-serializer-gson](https://github.com/KyoriPowered/adventure) from 4.8.1 to 4.9.2.
- [Release notes](https://github.com/KyoriPowered/adventure/releases)
- [Commits](https://github.com/KyoriPowered/adventure/compare/v4.8.1...v4.9.2)

---
updated-dependencies:
- dependency-name: net.kyori:adventure-text-serializer-gson
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-04 21:34:25 +00:00
Auxilor
a018a1fca5 Cleaned up dependencies 2021-10-03 18:57:52 +01:00
Auxilor
8a7b8f2b03 Cleaned up dependencies 2021-10-03 18:56:56 +01:00
Auxilor
abf3dc1e9e Updated to 6.9.4 2021-10-03 18:56:27 +01:00
Auxilor
e92cc41be6 Fixed BukkitAudiences bug on outdated versions of paper 2021-10-03 17:37:45 +01:00
Auxilor
49570c841b Reverted publication changes 2021-10-03 13:00:01 +01:00
Auxilor
9aa465844d Finally fixed Adventure + MiniMessage shading / Dependency issues 2021-10-03 12:54:38 +01:00
Auxilor
a692fbee01 Moved Adventure to api implementation, Removed GriefDefender 2021-10-03 11:51:55 +01:00
Auxilor
4223e8f17a Updated to 6.9.2 2021-10-02 12:20:37 +01:00
Auxilor
5f26b23a53 Adventure bug fixing 2021-10-02 12:20:27 +01:00
Auxilor
c8c179981c Adventure bug fixing 2021-10-02 12:20:05 +01:00
dependabot[bot]
4bb8bb62f9 Bump kotlin-gradle-plugin from 1.5.21 to 1.5.31
Bumps [kotlin-gradle-plugin](https://github.com/JetBrains/kotlin) from 1.5.21 to 1.5.31.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/v1.5.31/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.5.21...v1.5.31)

---
updated-dependencies:
- dependency-name: org.jetbrains.kotlin:kotlin-gradle-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-01 21:29:48 +00:00
70 changed files with 1166 additions and 819 deletions

View File

@@ -51,23 +51,20 @@ allprojects {
// CombatLogX
maven { url 'https://nexus.sirblobman.xyz/repository/public/' }
// Head Database
maven { url 'https://mvn.intellectualsites.com/content/groups/public/' }
}
dependencies {
compileOnly 'org.jetbrains:annotations:19.0.0'
// Lombok
compileOnly 'org.projectlombok:lombok:1.18.20'
compileOnly 'org.projectlombok:lombok:1.18.22'
annotationProcessor 'org.projectlombok:lombok:1.18.20'
testCompileOnly 'org.projectlombok:lombok:1.18.20'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.20'
// Test
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.3.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
}
tasks.withType(JavaCompile) {
@@ -87,7 +84,7 @@ allprojects {
shadowJar {
relocate('org.bstats', 'com.willfp.eco.shaded.bstats')
relocate('net.kyori.adventure', 'com.willfp.eco.shaded.adventure')
relocate('net.kyori.adventure.text.minimessage', 'com.willfp.eco.shaded.minimessage')
}
jar {

View File

@@ -6,14 +6,18 @@ group 'com.willfp'
version rootProject.version
dependencies {
// Adventure
compileOnly 'net.kyori:adventure-platform-bukkit:4.0.0'
compileOnly 'net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT'
compileOnly 'net.kyori:adventure-api:4.9.1'
compileOnly 'net.kyori:adventure-text-serializer-gson:4.9.2'
compileOnly 'net.kyori:adventure-text-serializer-legacy:4.8.1'
// Other
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
compileOnly 'org.apache.maven:maven-artifact:3.0.3'
compileOnly 'com.comphenix.protocol:ProtocolLib:4.6.0-SNAPSHOT'
compileOnly 'com.comphenix.protocol:ProtocolLib:4.7.1-SNAPSHOT'
compileOnly 'com.google.code.gson:gson:2.8.7'
compileOnly 'net.kyori:adventure-text-serializer-gson:4.8.1'
compileOnly 'net.kyori:adventure-text-serializer-legacy:4.8.1'
compileOnly 'net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT'
compileOnly 'net.kyori:adventure-platform-bukkit:4.0.0'
}
java {

View File

@@ -52,7 +52,7 @@ import java.util.stream.Collectors;
* be cancelled.</b>
*/
@SuppressWarnings("unused")
public abstract class EcoPlugin extends JavaPlugin {
public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
/**
* The polymart resource ID of the plugin.
*/

View File

@@ -210,6 +210,6 @@ public interface Handler {
*
* @return The audiences.
*/
@NotNull
@Nullable
BukkitAudiences getAdventure();
}

View File

@@ -0,0 +1,29 @@
package com.willfp.eco.core;
import com.willfp.eco.core.config.updating.ConfigHandler;
import java.io.File;
/**
* Represents any class that acts like a plugin, for example {@link EcoPlugin}
* or {@link com.willfp.eco.core.extensions.Extension}. This exists to create
* things such as extension base configs rather than needing to pass an instance
* of the owning plugin.
*/
public interface PluginLike {
/**
* Get the data folder of the object.
* <p>
* Returns the plugin data folder for a plugin, or the extension's parent plugin's folder
*
* @return The data folder.
*/
File getDataFolder();
/**
* Get the handler class for updatable classes.
*
* @return The config handler.
*/
ConfigHandler getConfigHandler();
}

View File

@@ -2,8 +2,8 @@ package com.willfp.eco.core.config.json;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
import org.jetbrains.annotations.NotNull;
/**
@@ -20,7 +20,7 @@ public abstract class JSONBaseConfig extends LoadableJSONConfigWrapper {
*/
protected JSONBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin,
@NotNull final PluginLike plugin,
@NotNull final String... updateBlacklist) {
super(
Eco.getHandler().getConfigFactory().createUpdatableJSONConfig(
@@ -40,7 +40,7 @@ public abstract class JSONBaseConfig extends LoadableJSONConfigWrapper {
*/
protected JSONBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin) {
@NotNull final PluginLike plugin) {
super(
Eco.getHandler().getConfigFactory().createUpdatableJSONConfig(
configName,
@@ -51,4 +51,28 @@ public abstract class JSONBaseConfig extends LoadableJSONConfigWrapper {
)
);
}
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
*/
protected JSONBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin,
@NotNull final String... updateBlacklist) {
this(configName, removeUnused, (PluginLike) plugin, updateBlacklist);
}
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
*/
protected JSONBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin) {
this(configName, removeUnused, (PluginLike) plugin);
}
}

View File

@@ -2,8 +2,8 @@ package com.willfp.eco.core.config.json;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
import org.jetbrains.annotations.NotNull;
/**
@@ -26,7 +26,7 @@ public abstract class JSONExtendableConfig extends LoadableJSONConfigWrapper {
*/
protected JSONExtendableConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin,
@NotNull final PluginLike plugin,
@NotNull final Class<?> source,
@NotNull final String subDirectoryPath,
@NotNull final String... updateBlacklist) {
@@ -41,4 +41,20 @@ public abstract class JSONExtendableConfig extends LoadableJSONConfigWrapper {
)
);
}
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
*/
protected JSONExtendableConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin,
@NotNull final Class<?> source,
@NotNull final String subDirectoryPath,
@NotNull final String... updateBlacklist) {
this(configName, removeUnused, (PluginLike) plugin, source, subDirectoryPath, updateBlacklist);
}
}

View File

@@ -2,6 +2,7 @@ package com.willfp.eco.core.config.json;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
import org.jetbrains.annotations.NotNull;
@@ -18,7 +19,20 @@ public abstract class JSONStaticBaseConfig extends LoadableJSONConfigWrapper {
* @param plugin The plugin.
*/
protected JSONStaticBaseConfig(@NotNull final String configName,
@NotNull final EcoPlugin plugin) {
@NotNull final PluginLike plugin) {
super(Eco.getHandler().getConfigFactory().createLoadableJSONConfig(configName, plugin, "", plugin.getClass()));
}
/**
* Config implementation for configs present in the plugin's base directory (eg config.json, lang.json).
* <p>
* Does not automatically update.
*
* @param configName The name of the config
* @param plugin The plugin.
*/
protected JSONStaticBaseConfig(@NotNull final String configName,
@NotNull final EcoPlugin plugin) {
this(configName, (PluginLike) plugin);
}
}

View File

@@ -4,7 +4,7 @@ import com.willfp.eco.core.config.interfaces.LoadableConfig;
import org.jetbrains.annotations.NotNull;
/**
* Every {@link com.willfp.eco.core.EcoPlugin} has a config handler.
* Every {@link com.willfp.eco.core.PluginLike} has a config handler.
* <p>
* Handles updating and saving configs.
*/

View File

@@ -1,6 +1,6 @@
package com.willfp.eco.core.config.wrapper;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import org.bukkit.configuration.file.YamlConfiguration;
@@ -24,7 +24,7 @@ public interface ConfigFactory {
* @return The config implementation.
*/
Config createUpdatableYamlConfig(@NotNull String configName,
@NotNull EcoPlugin plugin,
@NotNull PluginLike plugin,
@NotNull String subDirectoryPath,
@NotNull Class<?> source,
boolean removeUnused,
@@ -42,7 +42,7 @@ public interface ConfigFactory {
* @return The config implementation.
*/
JSONConfig createUpdatableJSONConfig(@NotNull String configName,
@NotNull EcoPlugin plugin,
@NotNull PluginLike plugin,
@NotNull String subDirectoryPath,
@NotNull Class<?> source,
boolean removeUnused,
@@ -58,7 +58,7 @@ public interface ConfigFactory {
* @return The config implementation.
*/
JSONConfig createLoadableJSONConfig(@NotNull String configName,
@NotNull EcoPlugin plugin,
@NotNull PluginLike plugin,
@NotNull String subDirectoryPath,
@NotNull Class<?> source);
@@ -72,7 +72,7 @@ public interface ConfigFactory {
* @return The config implementation.
*/
Config createLoadableYamlConfig(@NotNull String configName,
@NotNull EcoPlugin plugin,
@NotNull PluginLike plugin,
@NotNull String subDirectoryPath,
@NotNull Class<?> source);

View File

@@ -2,6 +2,7 @@ package com.willfp.eco.core.config.yaml;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
import org.jetbrains.annotations.NotNull;
@@ -19,7 +20,7 @@ public abstract class YamlBaseConfig extends LoadableYamlConfigWrapper {
*/
protected YamlBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin,
@NotNull final PluginLike plugin,
@NotNull final String... updateBlacklist) {
super(
Eco.getHandler().getConfigFactory().createUpdatableYamlConfig(
@@ -39,7 +40,7 @@ public abstract class YamlBaseConfig extends LoadableYamlConfigWrapper {
*/
protected YamlBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin) {
@NotNull final PluginLike plugin) {
super(
Eco.getHandler().getConfigFactory().createUpdatableYamlConfig(
configName,
@@ -50,4 +51,28 @@ public abstract class YamlBaseConfig extends LoadableYamlConfigWrapper {
)
);
}
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
*/
protected YamlBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin,
@NotNull final String... updateBlacklist) {
this(configName, removeUnused, (PluginLike) plugin, updateBlacklist);
}
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
*/
protected YamlBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin) {
this(configName, removeUnused, (PluginLike) plugin);
}
}

View File

@@ -2,6 +2,7 @@ package com.willfp.eco.core.config.yaml;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
import org.jetbrains.annotations.NotNull;
@@ -25,7 +26,7 @@ public abstract class YamlExtendableConfig extends LoadableYamlConfigWrapper {
*/
protected YamlExtendableConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin,
@NotNull final PluginLike plugin,
@NotNull final Class<?> source,
@NotNull final String subDirectoryPath,
@NotNull final String... updateBlacklist) {
@@ -40,4 +41,20 @@ public abstract class YamlExtendableConfig extends LoadableYamlConfigWrapper {
)
);
}
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
*/
protected YamlExtendableConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin,
@NotNull final Class<?> source,
@NotNull final String subDirectoryPath,
@NotNull final String... updateBlacklist) {
this(configName, removeUnused, (PluginLike) plugin, source, subDirectoryPath, updateBlacklist);
}
}

View File

@@ -2,6 +2,7 @@ package com.willfp.eco.core.config.yaml;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
import org.jetbrains.annotations.NotNull;
@@ -18,7 +19,20 @@ public abstract class YamlStaticBaseConfig extends LoadableYamlConfigWrapper {
* @param plugin The plugin.
*/
protected YamlStaticBaseConfig(@NotNull final String configName,
@NotNull final EcoPlugin plugin) {
@NotNull final PluginLike plugin) {
super(Eco.getHandler().getConfigFactory().createLoadableYamlConfig(configName, plugin, "", plugin.getClass()));
}
/**
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
* <p>
* Does not automatically update.
*
* @param configName The name of the config
* @param plugin The plugin.
*/
protected YamlStaticBaseConfig(@NotNull final String configName,
@NotNull final EcoPlugin plugin) {
this(configName, (PluginLike) plugin);
}
}

View File

@@ -1,11 +1,15 @@
package com.willfp.eco.core.extensions;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.updating.ConfigHandler;
import lombok.AccessLevel;
import lombok.Getter;
import org.apache.commons.lang.Validate;
import org.jetbrains.annotations.NotNull;
import java.io.File;
/**
* An extension is a separate jar file that hooks into the base plugin jar.
* <p>
@@ -15,9 +19,9 @@ import org.jetbrains.annotations.NotNull;
* Syntactically, extensions are very similar to plugins in their own right, except that
* they are loaded by another plugin.
*
* @see <a href="https://ecoenchants.polymart.org">EcoEnchants extension examples.</a>
* @see <a href="https://auxilor.polymart.org">Extension examples.</a>
*/
public abstract class Extension {
public abstract class Extension implements PluginLike {
/**
* The {@link EcoPlugin} that this extension is for.
*/
@@ -103,4 +107,14 @@ public abstract class Extension {
Validate.notNull(metadata, "Metadata cannot be null!");
return this.metadata.version();
}
@Override
public File getDataFolder() {
return this.plugin.getDataFolder();
}
@Override
public ConfigHandler getConfigHandler() {
return this.plugin.getConfigHandler();
}
}

View File

@@ -29,6 +29,16 @@ public class AntigriefManager {
registered.add(antigrief);
}
/**
* Unregister an AntiGrief/Land Management integration.
*
* @param antigrief The integration to unregister.
*/
public void unregister(@NotNull final AntigriefWrapper antigrief) {
registered.removeIf(it -> it.getPluginName().equalsIgnoreCase(antigrief.getPluginName()));
registered.remove(antigrief);
}
/**
* Can player break block.
*

View File

@@ -1,11 +1,13 @@
package com.willfp.eco.core.items;
import com.willfp.eco.core.items.args.LookupArgParser;
import com.willfp.eco.core.items.provider.ItemProvider;
import com.willfp.eco.core.recipe.parts.EmptyTestableItem;
import com.willfp.eco.core.recipe.parts.MaterialTestableItem;
import com.willfp.eco.core.recipe.parts.ModifiedTestableItem;
import com.willfp.eco.core.recipe.parts.TestableStack;
import com.willfp.eco.util.NamespacedKeyUtils;
import com.willfp.eco.util.NumberUtils;
import lombok.experimental.UtilityClass;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
@@ -16,12 +18,12 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
* Class to manage all custom and vanilla items.
@@ -31,7 +33,12 @@ public final class Items {
/**
* All recipe parts.
*/
private static final Map<NamespacedKey, CustomItem> REGISTRY = new ConcurrentHashMap<>();
private static final Map<NamespacedKey, TestableItem> REGISTRY = new ConcurrentHashMap<>();
/**
* All item providers.
*/
private static final Map<String, ItemProvider> PROVIDERS = new ConcurrentHashMap<>();
/**
* All recipe parts.
@@ -42,11 +49,20 @@ public final class Items {
* Register a new custom item.
*
* @param key The key of the item.
* @param part The item.
* @param item The item.
*/
public void registerCustomItem(@NotNull final NamespacedKey key,
@NotNull final CustomItem part) {
REGISTRY.put(key, part);
@NotNull final TestableItem item) {
REGISTRY.put(key, item);
}
/**
* Register a new item provider.
*
* @param provider The provider.
*/
public void registerItemProvider(@NotNull final ItemProvider provider) {
PROVIDERS.put(provider.getNamespace(), provider);
}
/**
@@ -123,7 +139,20 @@ public final class Items {
}
if (split.length == 2) {
CustomItem part = REGISTRY.get(NamespacedKeyUtils.create(split[0], split[1]));
String namespace = split[0];
String keyID = split[1];
NamespacedKey namespacedKey = NamespacedKeyUtils.create(namespace, keyID);
TestableItem part = REGISTRY.get(namespacedKey);
if (part == null && PROVIDERS.containsKey(namespace)) {
ItemProvider provider = PROVIDERS.get(namespace);
item = provider.provideForKey(keyID);
if (item instanceof EmptyTestableItem || item == null) {
return new EmptyTestableItem();
}
registerCustomItem(namespacedKey, item);
}
/*
Legacy id:amount format
@@ -146,7 +175,7 @@ public final class Items {
This has been superseded by namespace:id amount
*/
if (split.length == 3) {
CustomItem part = REGISTRY.get(NamespacedKeyUtils.create(split[0], split[1]));
TestableItem part = REGISTRY.get(NamespacedKeyUtils.create(split[0], split[1]));
if (part == null) {
return new EmptyTestableItem();
}
@@ -215,7 +244,7 @@ public final class Items {
* @return If is recipe.
*/
public boolean isCustomItem(@NotNull final ItemStack itemStack) {
for (CustomItem item : REGISTRY.values()) {
for (TestableItem item : REGISTRY.values()) {
if (item.matches(itemStack)) {
return true;
}
@@ -231,9 +260,9 @@ public final class Items {
*/
@Nullable
public CustomItem getCustomItem(@NotNull final ItemStack itemStack) {
for (CustomItem item : REGISTRY.values()) {
for (TestableItem item : REGISTRY.values()) {
if (item.matches(itemStack)) {
return item;
return getOrWrap(item);
}
}
return null;
@@ -245,6 +274,27 @@ public final class Items {
* @return A set of all items.
*/
public Set<CustomItem> getCustomItems() {
return new HashSet<>(REGISTRY.values());
return REGISTRY.values().stream().map(Items::getOrWrap).collect(Collectors.toSet());
}
/**
* Return a CustomItem instance for a given TestableItem.
* <p>
* Used internally since 6.10.0 when the registration moved from {@link CustomItem}
* to {@link TestableItem} for added flexibility.
*
* @param item The item.
* @return The CustomItem.
*/
public CustomItem getOrWrap(@NotNull final TestableItem item) {
if (item instanceof CustomItem) {
return (CustomItem) item;
} else {
return new CustomItem(
NamespacedKeyUtils.createEcoKey("wrapped_" + NumberUtils.randInt(0, 100000)),
item::matches,
item.getItem()
);
}
}
}

View File

@@ -0,0 +1,40 @@
package com.willfp.eco.core.items.provider;
import com.willfp.eco.core.items.TestableItem;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Item providers are call-site registrations for items. In other words,
* they only register their items when a request is made. This is marginally
* slower, however it is required for certain plugins, and fixes bugs related to
* loading orders.
*
* @see TestableItem
*/
public abstract class ItemProvider {
/**
* The namespace.
*/
@Getter
private final String namespace;
/**
* Create a new ItemProvider for a specific namespace.
*
* @param namespace The namespace.
*/
protected ItemProvider(@NotNull final String namespace) {
this.namespace = namespace;
}
/**
* Provide a TestableItem for a given key.
*
* @param key The item ID.
* @return The TestableItem, or null if not found.
*/
@Nullable
public abstract TestableItem provideForKey(@NotNull final String key);
}

View File

@@ -1,8 +1,10 @@
package com.willfp.eco.util;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.Prerequisite;
import lombok.experimental.UtilityClass;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
@@ -20,7 +22,21 @@ public class PlayerUtils {
*/
@NotNull
public Audience getAudience(@NotNull final Player player) {
return Eco.getHandler().getAdventure().player(player);
BukkitAudiences adventure = Eco.getHandler().getAdventure();
if (Prerequisite.HAS_PAPER.isMet()) {
if (player instanceof Audience) {
return (Audience) player;
} else {
return Audience.empty();
}
} else {
if (adventure == null) {
return Audience.empty();
} else {
return adventure.player(player);
}
}
}
/**
@@ -31,6 +47,20 @@ public class PlayerUtils {
*/
@NotNull
public Audience getAudience(@NotNull final CommandSender sender) {
return Eco.getHandler().getAdventure().sender(sender);
BukkitAudiences adventure = Eco.getHandler().getAdventure();
if (Prerequisite.HAS_PAPER.isMet()) {
if (sender instanceof Audience) {
return (Audience) sender;
} else {
return Audience.empty();
}
} else {
if (adventure == null) {
return Audience.empty();
} else {
return adventure.sender(sender);
}
}
}
}

View File

@@ -1,6 +1,7 @@
package com.willfp.eco.util;
import com.google.common.collect.ImmutableList;
import com.willfp.eco.core.Prerequisite;
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager;
import lombok.experimental.UtilityClass;
import net.kyori.adventure.text.Component;
@@ -251,9 +252,11 @@ public class StringUtils {
processedMessage = PlaceholderManager.translatePlaceholders(processedMessage, player);
}
processedMessage = translateGradients(processedMessage);
processedMessage = translateMiniMessage(processedMessage);
processedMessage = translateHexColorCodes(processedMessage);
processedMessage = ChatColor.translateAlternateColorCodes('&', processedMessage);
if (Prerequisite.HAS_PAPER.isMet()) {
processedMessage = translateMiniMessage(processedMessage);
}
return processedMessage;
}

View File

@@ -4,7 +4,7 @@ buildscript {
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.21"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31"
}
}
@@ -18,4 +18,12 @@ subprojects {
compileOnly project(":eco-api")
compileOnly 'org.jetbrains.kotlin:kotlin-stdlib:1.5.31'
}
compileKotlin {
kotlinOptions {
jvmTarget = "16"
}
targetCompatibility = JavaVersion.VERSION_16
sourceCompatibility = JavaVersion.VERSION_16
}
}

View File

@@ -1,6 +1,7 @@
package com.willfp.eco.internal.config
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.PluginLike
import com.willfp.eco.core.config.interfaces.Config
import com.willfp.eco.core.config.interfaces.JSONConfig
import com.willfp.eco.core.config.wrapper.ConfigFactory
@@ -15,7 +16,7 @@ import org.bukkit.configuration.file.YamlConfiguration
class EcoConfigFactory : ConfigFactory {
override fun createUpdatableYamlConfig(
configName: String,
plugin: EcoPlugin,
plugin: PluginLike,
subDirectoryPath: String,
source: Class<*>,
removeUnused: Boolean,
@@ -33,7 +34,7 @@ class EcoConfigFactory : ConfigFactory {
override fun createUpdatableJSONConfig(
configName: String,
plugin: EcoPlugin,
plugin: PluginLike,
subDirectoryPath: String,
source: Class<*>,
removeUnused: Boolean,
@@ -51,7 +52,7 @@ class EcoConfigFactory : ConfigFactory {
override fun createLoadableJSONConfig(
configName: String,
plugin: EcoPlugin,
plugin: PluginLike,
subDirectoryPath: String,
source: Class<*>
): JSONConfig {
@@ -65,7 +66,7 @@ class EcoConfigFactory : ConfigFactory {
override fun createLoadableYamlConfig(
configName: String,
plugin: EcoPlugin,
plugin: PluginLike,
subDirectoryPath: String,
source: Class<*>
): Config {

View File

@@ -1,8 +1,7 @@
package com.willfp.eco.internal.config.json
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.PluginLike
import com.willfp.eco.core.config.interfaces.LoadableConfig
import org.jetbrains.annotations.NotNull
import java.io.*
import java.nio.file.Files
import java.nio.file.StandardOpenOption
@@ -10,7 +9,7 @@ import java.nio.file.StandardOpenOption
@Suppress("UNCHECKED_CAST")
open class EcoLoadableJSONConfig(
configName: String,
private val plugin: EcoPlugin,
private val plugin: PluginLike,
private val subDirectoryPath: String,
val source: Class<*>
) : EcoJSONConfigWrapper(), LoadableConfig {

View File

@@ -1,6 +1,6 @@
package com.willfp.eco.internal.config.json
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.PluginLike
import org.bukkit.configuration.InvalidConfigurationException
import org.bukkit.configuration.file.YamlConfiguration
import java.io.BufferedReader
@@ -10,7 +10,7 @@ import java.nio.charset.StandardCharsets
open class EcoUpdatableJSONConfig(
configName: String,
plugin: EcoPlugin,
plugin: PluginLike,
subDirectoryPath: String,
source: Class<*>,
private val removeUnused: Boolean,

View File

@@ -11,7 +11,6 @@ import com.willfp.eco.internal.config.yaml.EcoLoadableYamlConfig
import com.willfp.eco.internal.config.yaml.EcoUpdatableYamlConfig
import org.reflections.Reflections
import org.reflections.scanners.MethodAnnotationsScanner
import java.lang.reflect.Modifier
class EcoConfigHandler(
private val plugin: EcoPlugin
@@ -25,10 +24,6 @@ class EcoConfigHandler(
override fun callUpdate() {
for (method in reflections.getMethodsAnnotatedWith(ConfigUpdater::class.java)) {
if (!Modifier.isStatic(method.modifiers)) {
throw InvalidUpdateMethodException("Update method in ${method.declaringClass.name} must be static.")
}
try {
when (method.parameterCount) {
0 -> method.invoke(null)

View File

@@ -1,6 +1,6 @@
package com.willfp.eco.internal.config.yaml
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.PluginLike
import com.willfp.eco.core.config.interfaces.LoadableConfig
import com.willfp.eco.core.config.interfaces.WrappedYamlConfiguration
import org.bukkit.configuration.InvalidConfigurationException
@@ -12,7 +12,7 @@ import java.io.OutputStream
open class EcoLoadableYamlConfig(
configName: String,
private val plugin: EcoPlugin,
private val plugin: PluginLike,
private val subDirectoryPath: String,
val source: Class<*>
) : EcoYamlConfigWrapper<YamlConfiguration>(), WrappedYamlConfiguration, LoadableConfig {

View File

@@ -1,6 +1,6 @@
package com.willfp.eco.internal.config.yaml
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.PluginLike
import org.bukkit.configuration.InvalidConfigurationException
import org.bukkit.configuration.file.YamlConfiguration
import java.io.BufferedReader
@@ -10,7 +10,7 @@ import java.nio.charset.StandardCharsets
class EcoUpdatableYamlConfig(
configName: String,
plugin: EcoPlugin,
plugin: PluginLike,
subDirectoryPath: String,
source: Class<*>,
private val removeUnused: Boolean,
@@ -27,9 +27,9 @@ class EcoUpdatableYamlConfig(
if (newConfig.getKeys(true) == this.handle.getKeys(true)) {
return
}
newConfig.getKeys(true).forEach { key: String ->
newConfig.getKeys(true).forEach { key ->
if (!this.handle.getKeys(true).contains(key)) {
if (updateBlacklist.stream().noneMatch { s: String -> key.contains(s) }) {
if (updateBlacklist.stream().noneMatch { key.contains(it) }) {
this.handle.set(key, newConfig[key])
}
}
@@ -67,7 +67,7 @@ class EcoUpdatableYamlConfig(
}
init {
this.updateBlacklist.removeIf { obj: String -> obj.isEmpty() }
this.updateBlacklist.removeIf { it.isEmpty() }
plugin.configHandler.addConfig(this)
update()
}

View File

@@ -3,4 +3,6 @@ version rootProject.version
dependencies {
compileOnly 'org.spigotmc:spigot:1.16.5-R0.1-SNAPSHOT'
compileOnly 'net.kyori:adventure-api:4.9.1'
compileOnly 'net.kyori:adventure-text-serializer-gson:4.8.1'
}

View File

@@ -1,118 +0,0 @@
package com.willfp.eco.proxy.v1_16_R3;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.willfp.eco.core.display.Display;
import com.willfp.eco.proxy.ChatComponentProxy;
import net.minecraft.server.v1_16_R3.ChatBaseComponent;
import net.minecraft.server.v1_16_R3.ChatHoverable;
import net.minecraft.server.v1_16_R3.ChatMessage;
import net.minecraft.server.v1_16_R3.ChatModifier;
import net.minecraft.server.v1_16_R3.IChatBaseComponent;
import net.minecraft.server.v1_16_R3.MojangsonParser;
import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
public final class ChatComponent implements ChatComponentProxy {
@Override
public Object modifyComponent(@NotNull final Object obj,
@NotNull final Player player) {
if (!(obj instanceof IChatBaseComponent chatComponent)) {
return obj;
}
for (IChatBaseComponent iChatBaseComponent : chatComponent) {
if (iChatBaseComponent == null) {
continue;
}
modifyBaseComponent(iChatBaseComponent, player);
}
return chatComponent;
}
private void modifyBaseComponent(@NotNull final IChatBaseComponent component,
@NotNull final Player player) {
for (IChatBaseComponent sibling : component.getSiblings()) {
if (sibling == null) {
continue;
}
modifyBaseComponent(sibling, player);
}
if (component instanceof ChatMessage) {
Arrays.stream(((ChatMessage) component).getArgs())
.filter(o -> o instanceof IChatBaseComponent)
.map(o -> (IChatBaseComponent) o)
.forEach(o -> this.modifyBaseComponent(o, player));
}
ChatHoverable hoverable = component.getChatModifier().getHoverEvent();
if (hoverable == null) {
return;
}
JsonObject jsonObject = hoverable.b();
JsonElement json = hoverable.b().get("contents");
if (json.getAsJsonObject().get("id") == null) {
return;
}
if (json.getAsJsonObject().get("tag") == null) {
return;
}
String id = json.getAsJsonObject().get("id").toString();
String tag = json.getAsJsonObject().get("tag").toString();
ItemStack itemStack = getFromTag(tag, id);
Display.displayAndFinalize(itemStack, player);
json.getAsJsonObject().remove("tag");
String newTag = toJson(itemStack);
json.getAsJsonObject().add("tag", new JsonPrimitive(newTag));
jsonObject.remove("contents");
jsonObject.add("contents", json);
ChatHoverable newHoverable = ChatHoverable.a(jsonObject);
ChatModifier modifier = component.getChatModifier();
modifier = modifier.setChatHoverable(newHoverable);
((ChatBaseComponent) component).setChatModifier(modifier);
}
private static ItemStack getFromTag(@NotNull final String jsonTag,
@NotNull final String id) {
String processedId = id;
String processedJsonTag = jsonTag;
processedId = processedId.replace("minecraft:", "");
processedId = processedId.toUpperCase();
processedId = processedId.replace("\"", "");
processedJsonTag = processedJsonTag.substring(1, processedJsonTag.length() - 1);
processedJsonTag = processedJsonTag.replace("id:", "\"id\":");
processedJsonTag = processedJsonTag.replace("\\", "");
Material material = Material.getMaterial(processedId);
assert material != null;
ItemStack itemStack = new ItemStack(material);
net.minecraft.server.v1_16_R3.ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack);
try {
nmsStack.setTag(MojangsonParser.parse(processedJsonTag));
} catch (CommandSyntaxException e) {
e.printStackTrace();
}
return CraftItemStack.asBukkitCopy(nmsStack);
}
private static String toJson(@NotNull final ItemStack itemStack) {
return CraftItemStack.asNMSCopy(itemStack).getOrCreateTag().toString();
}
}

View File

@@ -1,43 +0,0 @@
package com.willfp.eco.proxy.v1_16_R3;
import org.bukkit.craftbukkit.libs.org.apache.commons.lang3.Validate;
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
public class FastItemStackUtils {
private static final Field FIELD;
public static net.minecraft.server.v1_16_R3.ItemStack getNMSStack(@NotNull final ItemStack itemStack) {
if (!(itemStack instanceof CraftItemStack)) {
return CraftItemStack.asNMSCopy(itemStack);
} else {
try {
net.minecraft.server.v1_16_R3.ItemStack nms = (net.minecraft.server.v1_16_R3.ItemStack) FIELD.get(itemStack);
return nms == null ? CraftItemStack.asNMSCopy(itemStack) : nms;
} catch (ReflectiveOperationException e) {
e.printStackTrace();
return net.minecraft.server.v1_16_R3.ItemStack.b;
}
}
}
static {
Field temp = null;
try {
Field handleField = CraftItemStack.class.getDeclaredField("handle");
handleField.setAccessible(true);
temp = handleField;
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
assert temp != null;
Validate.notNull(temp, "Error occurred in initialization!");
FIELD = temp;
}
}

View File

@@ -0,0 +1,93 @@
package com.willfp.eco.proxy.v1_16_R3
import com.willfp.eco.core.display.Display
import com.willfp.eco.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.server.v1_16_R3.IChatBaseComponent
import net.minecraft.server.v1_16_R3.MojangsonParser
import org.bukkit.Material
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack
import org.bukkit.entity.Player
@Suppress("UNCHECKED_CAST")
class ChatComponent : ChatComponentProxy {
private val gsonComponentSerializer = GsonComponentSerializer.gson()
override fun modifyComponent(obj: Any, player: Player): Any {
if (obj !is IChatBaseComponent) {
return obj
}
val component = gsonComponentSerializer.deserialize(
IChatBaseComponent.ChatSerializer.a(
obj
)
).asComponent() as BuildableComponent<*, *>
val newComponent = modifyBaseComponent(component, player)
return IChatBaseComponent.ChatSerializer.a(
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.of(
CraftItemStack.asNMSCopy(
Display.display(
CraftItemStack.asBukkitCopy(
CraftItemStack.asNMSCopy(
org.bukkit.inventory.ItemStack(
Material.matchMaterial(
showItem.item()
.toString()
) ?: return component,
showItem.count()
)
).apply {
this.tag = MojangsonParser.parse(
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)
}
}

View File

@@ -0,0 +1,17 @@
package com.willfp.eco.proxy.v1_16_R3.fast
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack
import org.bukkit.inventory.ItemStack
import java.lang.reflect.Field
private val field: Field = CraftItemStack::class.java.getDeclaredField("handle").apply {
isAccessible = true
}
fun ItemStack.getNMSStack(): net.minecraft.server.v1_16_R3.ItemStack {
return if (this !is CraftItemStack) {
CraftItemStack.asNMSCopy(this)
} else {
field[this] as net.minecraft.server.v1_16_R3.ItemStack? ?: CraftItemStack.asNMSCopy(this)
}
}

View File

@@ -1,7 +1,6 @@
package com.willfp.eco.proxy.v1_16_R3.fast
import com.willfp.eco.internal.fast.EcoFastItemStack
import com.willfp.eco.proxy.v1_16_R3.FastItemStackUtils
import com.willfp.eco.util.StringUtils
import net.minecraft.server.v1_16_R3.*
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack
@@ -12,7 +11,7 @@ import org.bukkit.inventory.ItemFlag
import kotlin.experimental.and
class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemStack<ItemStack>(
FastItemStackUtils.getNMSStack(itemStack), itemStack
itemStack.getNMSStack(), itemStack
) {
private var loreCache: List<String>? = null
override fun getEnchantmentsOnItem(checkStored: Boolean): Map<Enchantment, Int> {
@@ -151,6 +150,18 @@ class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemS
handle.repairCost = cost
}
override fun equals(other: Any?): Boolean {
if (other !is NMSFastItemStack) {
return false
}
return other.hashCode() == this.hashCode()
}
override fun hashCode(): Int {
return handle.tag.hashCode() * 31 + Item.getId(handle.item)
}
private fun apply() {
if (bukkit !is CraftItemStack) {
bukkit.itemMeta = CraftItemStack.asCraftMirror(handle).itemMeta

View File

@@ -7,6 +7,8 @@ version rootProject.version
dependencies {
compileOnly 'org.spigotmc:spigot:1.17.1-R0.1-SNAPSHOT:remapped-mojang'
compileOnly 'net.kyori:adventure-api:4.9.1'
compileOnly 'net.kyori:adventure-text-serializer-gson:4.8.1'
}
specialGradle {

View File

@@ -1,118 +0,0 @@
package com.willfp.eco.proxy.v1_17_R1;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.willfp.eco.core.display.Display;
import net.minecraft.nbt.TagParser;
import net.minecraft.network.chat.BaseComponent;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.HoverEvent;
import net.minecraft.network.chat.Style;
import net.minecraft.network.chat.TranslatableComponent;
import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import com.willfp.eco.proxy.ChatComponentProxy;
public final class ChatComponent implements ChatComponentProxy {
@Override
public Object modifyComponent(@NotNull final Object obj,
@NotNull final Player player) {
if (!(obj instanceof Component chatComponent)) {
return obj;
}
for (Component iChatBaseComponent : chatComponent) {
if (iChatBaseComponent == null) {
continue;
}
modifyBaseComponent(iChatBaseComponent, player);
}
return chatComponent;
}
private void modifyBaseComponent(@NotNull final Component component,
@NotNull final Player player) {
for (Component sibling : component.getSiblings()) {
if (sibling == null) {
continue;
}
modifyBaseComponent(sibling, player);
}
if (component instanceof TranslatableComponent baseComponent) {
for (Object arg : baseComponent.getArgs()) {
if (arg instanceof Component) {
modifyBaseComponent((Component) arg, player);
}
}
}
HoverEvent hoverable = component.getStyle().getHoverEvent();
if (hoverable == null) {
return;
}
JsonObject jsonObject = hoverable.serialize();
JsonElement json = jsonObject.get("contents");
if (json.getAsJsonObject().get("id") == null) {
return;
}
if (json.getAsJsonObject().get("tag") == null) {
return;
}
String id = json.getAsJsonObject().get("id").toString();
String tag = json.getAsJsonObject().get("tag").toString();
ItemStack itemStack = getFromTag(tag, id);
Display.displayAndFinalize(itemStack, player);
json.getAsJsonObject().remove("tag");
String newTag = toJson(itemStack);
json.getAsJsonObject().add("tag", new JsonPrimitive(newTag));
jsonObject.remove("contents");
jsonObject.add("contents", json);
HoverEvent newHoverable = HoverEvent.deserialize(jsonObject);
Style modifier = component.getStyle();
modifier = modifier.withHoverEvent(newHoverable);
((BaseComponent) component).setStyle(modifier);
}
private static ItemStack getFromTag(@NotNull final String jsonTag,
@NotNull final String id) {
String processedId = id;
String processedJsonTag = jsonTag;
processedId = processedId.replace("minecraft:", "");
processedId = processedId.toUpperCase();
processedId = processedId.replace("\"", "");
processedJsonTag = processedJsonTag.substring(1, processedJsonTag.length() - 1);
processedJsonTag = processedJsonTag.replace("id:", "\"id\":");
processedJsonTag = processedJsonTag.replace("\\", "");
Material material = Material.getMaterial(processedId);
assert material != null;
ItemStack itemStack = new ItemStack(material);
net.minecraft.world.item.ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack);
try {
nmsStack.setTag(TagParser.parseTag(processedJsonTag));
} catch (CommandSyntaxException e) {
e.printStackTrace();
}
return CraftItemStack.asBukkitCopy(nmsStack);
}
private static String toJson(@NotNull final ItemStack itemStack) {
return CraftItemStack.asNMSCopy(itemStack).getOrCreateTag().toString();
}
}

View File

@@ -1,45 +0,0 @@
package com.willfp.eco.proxy.v1_17_R1;
import lombok.experimental.UtilityClass;
import org.bukkit.craftbukkit.libs.org.apache.commons.lang3.Validate;
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
@UtilityClass
public class FastItemStackUtils {
private static final Field FIELD;
public static net.minecraft.world.item.ItemStack getNMSStack(@NotNull final ItemStack itemStack) {
if (!(itemStack instanceof CraftItemStack)) {
return CraftItemStack.asNMSCopy(itemStack);
} else {
try {
net.minecraft.world.item.ItemStack nms = (net.minecraft.world.item.ItemStack) FIELD.get(itemStack);
return nms == null ? CraftItemStack.asNMSCopy(itemStack) : nms;
} catch (ReflectiveOperationException e) {
e.printStackTrace();
return net.minecraft.world.item.ItemStack.EMPTY;
}
}
}
static {
Field temp = null;
try {
Field handleField = CraftItemStack.class.getDeclaredField("handle");
handleField.setAccessible(true);
temp = handleField;
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
assert temp != null;
Validate.notNull(temp, "Error occurred in initialization!");
FIELD = temp;
}
}

View File

@@ -0,0 +1,93 @@
package com.willfp.eco.proxy.v1_17_R1
import com.willfp.eco.core.display.Display
import com.willfp.eco.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_17_R1.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.of(
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)
}
}

View File

@@ -0,0 +1,17 @@
package com.willfp.eco.proxy.v1_17_R1.fast
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack
import org.bukkit.inventory.ItemStack
import java.lang.reflect.Field
private val field: Field = CraftItemStack::class.java.getDeclaredField("handle").apply {
isAccessible = true
}
fun ItemStack.getNMSStack(): net.minecraft.world.item.ItemStack {
return if (this !is CraftItemStack) {
CraftItemStack.asNMSCopy(this)
} else {
field[this] as net.minecraft.world.item.ItemStack? ?: CraftItemStack.asNMSCopy(this)
}
}

View File

@@ -1,12 +1,12 @@
package com.willfp.eco.proxy.v1_17_R1.fast
import com.willfp.eco.internal.fast.EcoFastItemStack
import com.willfp.eco.proxy.v1_17_R1.FastItemStackUtils
import com.willfp.eco.util.StringUtils
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.ListTag
import net.minecraft.nbt.StringTag
import net.minecraft.world.item.EnchantedBookItem
import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack
@@ -17,7 +17,7 @@ import org.bukkit.inventory.ItemFlag
import kotlin.experimental.and
class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemStack<ItemStack>(
FastItemStackUtils.getNMSStack(itemStack), itemStack
itemStack.getNMSStack(), itemStack
) {
private var loreCache: List<String>? = null
@@ -171,6 +171,18 @@ class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemS
handle.setRepairCost(cost)
}
override fun equals(other: Any?): Boolean {
if (other !is NMSFastItemStack) {
return false
}
return other.hashCode() == this.hashCode()
}
override fun hashCode(): Int {
return handle.tag.hashCode() * 31 + Item.getId(handle.item)
}
private fun apply() {
if (bukkit !is CraftItemStack) {
bukkit.itemMeta = CraftItemStack.asCraftMirror(handle).itemMeta

View File

@@ -3,32 +3,33 @@ version rootProject.version
dependencies {
implementation 'org.bstats:bstats-bukkit:1.7'
implementation 'net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT'
implementation 'net.kyori:adventure-platform-bukkit:4.0.0'
implementation 'net.kyori:adventure-api:4.9.1'
implementation 'net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT'
implementation 'net.kyori:adventure-text-serializer-gson:4.8.1'
implementation 'net.kyori:adventure-text-serializer-legacy:4.8.1'
implementation('net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT') {
exclude group: 'net.kyori', module: 'adventure-api'
}
compileOnly 'net.kyori:adventure-platform-bukkit:4.0.0'
compileOnly 'net.kyori:adventure-api:4.9.1'
compileOnly 'net.kyori:adventure-text-serializer-gson:4.9.2'
compileOnly 'net.kyori:adventure-text-serializer-legacy:4.8.1'
compileOnly 'org.apache.maven:maven-artifact:3.0.3'
compileOnly 'com.google.code.gson:gson:2.8.7'
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
compileOnly project(":eco-core:core-proxy")
compileOnly project(":eco-core:core-backend")
compileOnly 'com.comphenix.protocol:ProtocolLib:4.6.0-SNAPSHOT'
compileOnly 'com.sk89q.worldguard:worldguard-bukkit:7.0.4-SNAPSHOT'
compileOnly 'com.comphenix.protocol:ProtocolLib:4.7.1-SNAPSHOT'
compileOnly 'com.sk89q.worldguard:worldguard-bukkit:7.0.7-SNAPSHOT'
compileOnly 'com.github.TechFortress:GriefPrevention:16.17.1'
compileOnly 'com.massivecraft:Factions:1.6.9.5-U0.5.10'
compileOnly 'com.github.cryptomorin:kingdoms:1.10.14'
compileOnly 'com.github.TownyAdvanced:Towny:0.97.1.0'
compileOnly 'com.github.TownyAdvanced:Towny:0.97.2.5'
compileOnly 'com.github.angeschossen:LandsAPI:4.7.3'
compileOnly 'fr.neatmonster:nocheatplus:3.16.1-SNAPSHOT'
compileOnly 'com.github.jiangdashao:matrix-api-repo:317d4635fd'
compileOnly 'com.gmail.nossr50.mcMMO:mcMMO:2.1.157'
compileOnly 'com.gmail.nossr50.mcMMO:mcMMO:2.1.202'
compileOnly 'me.clip:placeholderapi:2.10.10'
compileOnly 'com.willfp:Oraxen:e1f4003d8d'
compileOnly 'com.github.brcdev-minecraft:shopgui-api:2.2.0'
compileOnly 'com.github.LoneDev6:API-ItemsAdder:2.4.7'
compileOnly 'me.arcaniax:HeadDatabase-API:1.2.0'
compileOnly 'com.arcaniax:HeadDatabase-API:1.3.0'
// CombatLogX V10 + NewbieHelper Expansion
compileOnly 'com.SirBlobman.combatlogx:CombatLogX-API:10.0.0.0-SNAPSHOT'

View File

@@ -1,42 +0,0 @@
package com.willfp.eco.spigot.eventlisteners;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginDependent;
import com.willfp.eco.core.events.ArmorChangeEvent;
import com.willfp.eco.core.events.ArmorEquipEvent;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@SuppressWarnings("deprecation")
public class ArmorChangeEventListeners extends PluginDependent<EcoPlugin> implements Listener {
/**
* Pass an {@link EcoPlugin} in order to interface with it.
*
* @param plugin The plugin to manage.
*/
public ArmorChangeEventListeners(@NotNull final EcoPlugin plugin) {
super(plugin);
}
@EventHandler
public void onArmorChange(@NotNull final ArmorEquipEvent event) {
Player player = event.getPlayer();
List<ItemStack> before = new ArrayList<>(Arrays.asList(player.getInventory().getArmorContents()));
this.getPlugin().getScheduler().runLater(() -> {
List<ItemStack> after = new ArrayList<>(Arrays.asList(player.getInventory().getArmorContents()));
ArmorChangeEvent armorChangeEvent = new ArmorChangeEvent(player, before, after);
Bukkit.getPluginManager().callEvent(armorChangeEvent);
}, 1);
}
}

View File

@@ -1,187 +0,0 @@
package com.willfp.eco.spigot.eventlisteners;
import com.willfp.eco.core.events.ArmorEquipEvent;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.Event.Result;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryDragEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.inventory.InventoryType.SlotType;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerItemBreakEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@SuppressWarnings("deprecation")
public class ArmorListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public final void inventoryClick(@NotNull final InventoryClickEvent event) {
boolean shift = false;
boolean numberkey = false;
if (event.isCancelled()) {
return;
}
if (event.getAction() == InventoryAction.NOTHING) {
return;
}
if (event.getClick().equals(ClickType.SHIFT_LEFT) || event.getClick().equals(ClickType.SHIFT_RIGHT)) {
shift = true;
}
if (event.getClick().equals(ClickType.NUMBER_KEY)) {
numberkey = true;
}
if (event.getSlotType() != SlotType.ARMOR && event.getSlotType() != SlotType.QUICKBAR && event.getSlotType() != SlotType.CONTAINER) {
return;
}
if (event.getClickedInventory() != null && !event.getClickedInventory().getType().equals(InventoryType.PLAYER)) {
return;
}
if (!event.getInventory().getType().equals(InventoryType.CRAFTING) && !event.getInventory().getType().equals(InventoryType.PLAYER)) {
return;
}
if (!(event.getWhoClicked() instanceof Player)) {
return;
}
ArmorType newArmorType = ArmorType.matchType(shift ? event.getCurrentItem() : event.getCursor());
if (!shift && newArmorType != null && event.getRawSlot() != newArmorType.getSlot()) {
// Used for drag and drop checking to make sure you aren't trying to place a helmet in the boots slot.
return;
}
if (shift) {
newArmorType = ArmorType.matchType(event.getCurrentItem());
if (newArmorType != null) {
boolean equipping = true;
if (event.getRawSlot() == newArmorType.getSlot()) {
equipping = false;
}
if (newArmorType.equals(ArmorType.HELMET)
&& (equipping == isAirOrNull(event.getWhoClicked().getInventory().getHelmet()))
|| newArmorType.equals(ArmorType.CHESTPLATE)
&& (equipping == isAirOrNull(event.getWhoClicked().getInventory().getChestplate()))
|| newArmorType.equals(ArmorType.LEGGINGS)
&& (equipping == isAirOrNull(event.getWhoClicked().getInventory().getLeggings()))
|| newArmorType.equals(ArmorType.BOOTS)
&& (equipping == isAirOrNull(event.getWhoClicked().getInventory().getBoots()))) {
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(
(Player) event.getWhoClicked()
);
Bukkit.getPluginManager().callEvent(armorEquipEvent);
}
}
} else {
if (numberkey) {
if (event.getClickedInventory().getType().equals(InventoryType.PLAYER)) {
ItemStack hotbarItem = event.getClickedInventory().getItem(event.getHotbarButton());
if (!isAirOrNull(hotbarItem)) {
newArmorType = ArmorType.matchType(hotbarItem);
} else {
newArmorType = ArmorType.matchType(!isAirOrNull(event.getCurrentItem()) ? event.getCurrentItem() : event.getCursor());
}
}
} else {
if (isAirOrNull(event.getCursor()) && !isAirOrNull(event.getCurrentItem())) {
newArmorType = ArmorType.matchType(event.getCurrentItem());
}
}
if (newArmorType != null && event.getRawSlot() == newArmorType.getSlot()) {
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent((Player) event.getWhoClicked());
Bukkit.getPluginManager().callEvent(armorEquipEvent);
}
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void playerInteractEvent(@NotNull final PlayerInteractEvent e) {
if (e.useItemInHand().equals(Result.DENY)) {
return;
}
if (e.getAction() == Action.PHYSICAL) {
return;
}
if (e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK) {
Player player = e.getPlayer();
if (!e.useInteractedBlock().equals(Result.DENY)) {
if (e.getClickedBlock() != null && e.getAction() == Action.RIGHT_CLICK_BLOCK && !player.isSneaking()) {
Material mat = e.getClickedBlock().getType();
}
}
ArmorType newArmorType = ArmorType.matchType(e.getItem());
if (newArmorType != null) {
if (newArmorType.equals(ArmorType.HELMET)
&& isAirOrNull(e.getPlayer().getInventory().getHelmet())
|| newArmorType.equals(ArmorType.CHESTPLATE)
&& isAirOrNull(e.getPlayer().getInventory().getChestplate())
|| newArmorType.equals(ArmorType.LEGGINGS)
&& isAirOrNull(e.getPlayer().getInventory().getLeggings())
|| newArmorType.equals(ArmorType.BOOTS)
&& isAirOrNull(e.getPlayer().getInventory().getBoots())) {
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(e.getPlayer());
Bukkit.getPluginManager().callEvent(armorEquipEvent);
}
}
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void inventoryDrag(@NotNull final InventoryDragEvent event) {
ArmorType type = ArmorType.matchType(event.getOldCursor());
if (event.getRawSlots().isEmpty()) {
return;
}
if (type != null && type.getSlot() == event.getRawSlots().stream().findFirst().orElse(0)) {
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent((Player) event.getWhoClicked());
Bukkit.getPluginManager().callEvent(armorEquipEvent);
}
}
@EventHandler
public void playerJoinEvent(@NotNull final PlayerJoinEvent event) {
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(event.getPlayer());
Bukkit.getPluginManager().callEvent(armorEquipEvent);
}
@EventHandler
public void playerRespawnEvent(@NotNull final PlayerRespawnEvent event) {
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(event.getPlayer());
Bukkit.getPluginManager().callEvent(armorEquipEvent);
}
@EventHandler
public void itemBreakEvent(@NotNull final PlayerItemBreakEvent event) {
ArmorType type = ArmorType.matchType(event.getBrokenItem());
if (type != null) {
Player p = event.getPlayer();
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(p);
Bukkit.getPluginManager().callEvent(armorEquipEvent);
}
}
@EventHandler
public void playerDeathEvent(@NotNull final PlayerDeathEvent event) {
Player p = event.getEntity();
if (event.getKeepInventory()) {
return;
}
for (ItemStack i : p.getInventory().getArmorContents()) {
if (!isAirOrNull(i)) {
Bukkit.getPluginManager().callEvent(new ArmorEquipEvent(p));
}
}
}
public static boolean isAirOrNull(@Nullable final ItemStack item) {
return item == null || item.getType().equals(Material.AIR);
}
}

View File

@@ -1,38 +0,0 @@
package com.willfp.eco.spigot.eventlisteners;
import org.bukkit.inventory.ItemStack;
public enum ArmorType {
HELMET(5),
CHESTPLATE(6),
LEGGINGS(7),
BOOTS(8);
private final int slot;
ArmorType(final int slot) {
this.slot = slot;
}
public static ArmorType matchType(final ItemStack itemStack) {
if (ArmorListener.isAirOrNull(itemStack)) {
return null;
}
String type = itemStack.getType().name();
if (type.endsWith("_HELMET") || type.endsWith("_SKULL") || type.endsWith("PLAYER_HEAD")) {
return HELMET;
} else if (type.endsWith("_CHESTPLATE") || type.endsWith("ELYTRA")) {
return CHESTPLATE;
} else if (type.endsWith("_LEGGINGS")) {
return LEGGINGS;
} else if (type.endsWith("_BOOTS")) {
return BOOTS;
} else {
return null;
}
}
public int getSlot() {
return slot;
}
}

View File

@@ -1,21 +0,0 @@
package com.willfp.eco.spigot.eventlisteners;
import com.willfp.eco.core.events.ArmorEquipEvent;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockDispenseArmorEvent;
import org.jetbrains.annotations.NotNull;
@SuppressWarnings("deprecation")
public class DispenserArmorListener implements Listener {
@EventHandler
public void dispenseArmorEvent(@NotNull final BlockDispenseArmorEvent event) {
ArmorType type = ArmorType.matchType(event.getItem());
if (type != null && event.getTargetEntity() instanceof Player p) {
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(p);
Bukkit.getPluginManager().callEvent(armorEquipEvent);
}
}
}

View File

@@ -43,7 +43,7 @@ import java.util.logging.Logger
class EcoHandler : EcoSpigotPlugin(), Handler {
private val cleaner = EcoCleaner()
private val requirementFactory = EcoRequirementFactory()
private lateinit var adventure: BukkitAudiences
private var adventure: BukkitAudiences? = null
override fun createScheduler(plugin: EcoPlugin): Scheduler {
return EcoScheduler(plugin)
@@ -129,7 +129,7 @@ class EcoHandler : EcoSpigotPlugin(), Handler {
return requirementFactory
}
override fun getAdventure(): BukkitAudiences {
override fun getAdventure(): BukkitAudiences? {
return adventure
}

View File

@@ -3,6 +3,7 @@ package com.willfp.eco.spigot
import com.willfp.eco.core.AbstractPacketAdapter
import com.willfp.eco.core.Eco
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.Prerequisite
import com.willfp.eco.core.display.Display
import com.willfp.eco.core.integrations.IntegrationLoader
import com.willfp.eco.core.integrations.anticheat.AnticheatManager
@@ -20,14 +21,21 @@ import com.willfp.eco.proxy.FastItemStackFactoryProxy
import com.willfp.eco.proxy.SkullProxy
import com.willfp.eco.spigot.arrows.ArrowDataListener
import com.willfp.eco.spigot.display.*
import com.willfp.eco.spigot.display.frame.clearFrames
import com.willfp.eco.spigot.drops.CollatedRunnable
import com.willfp.eco.spigot.eventlisteners.*
import com.willfp.eco.spigot.eventlisteners.EntityDeathByEntityListeners
import com.willfp.eco.spigot.eventlisteners.NaturalExpGainListeners
import com.willfp.eco.spigot.eventlisteners.PlayerJumpListeners
import com.willfp.eco.spigot.eventlisteners.armor.ArmorChangeEventListeners
import com.willfp.eco.spigot.eventlisteners.armor.ArmorListener
import com.willfp.eco.spigot.gui.GUIListener
import com.willfp.eco.spigot.integrations.anticheat.*
import com.willfp.eco.spigot.integrations.antigrief.*
import com.willfp.eco.spigot.integrations.customitems.CustomItemsHeadDatabase
import com.willfp.eco.spigot.integrations.customitems.CustomItemsItemsAdder
import com.willfp.eco.spigot.integrations.customitems.CustomItemsOraxen
import com.willfp.eco.spigot.integrations.mcmmo.McmmoIntegrationImpl
import com.willfp.eco.spigot.integrations.multiverseinventories.MultiverseInventoriesIntegration
import com.willfp.eco.spigot.integrations.shop.ShopShopGuiPlus
import com.willfp.eco.spigot.recipes.ShapedRecipeListener
import com.willfp.eco.util.BlockUtils
@@ -69,7 +77,10 @@ abstract class EcoSpigotPlugin : EcoPlugin(
override fun handleEnable() {
CollatedRunnable(this)
(Eco.getHandler() as EcoHandler).adventure = BukkitAudiences.create(this)
if (!Prerequisite.HAS_PAPER.isMet) {
(Eco.getHandler() as EcoHandler).setAdventure(BukkitAudiences.create(this))
}
this.logger.info("Ignore messages about deprecated events!")
@@ -91,12 +102,17 @@ abstract class EcoSpigotPlugin : EcoPlugin(
}
override fun handleDisable() {
Eco.getHandler().adventure.close()
Eco.getHandler().adventure?.close()
}
override fun handleReload() {
CollatedRunnable(this)
DropManager.update(this)
this.scheduler.runTimer(
{ clearFrames() },
this.configYml.getInt("display-frame-ttl").toLong(),
this.configYml.getInt("display-frame-ttl").toLong()
)
}
override fun handleAfterLoad() {
@@ -109,7 +125,6 @@ abstract class EcoSpigotPlugin : EcoPlugin(
// AntiGrief
IntegrationLoader("WorldGuard") { AntigriefManager.register(AntigriefWorldGuard()) },
IntegrationLoader("GriefPrevention") { AntigriefManager.register(AntigriefGriefPrevention()) },
IntegrationLoader("GriefDefender") { AntigriefManager.register(AntigriefGriefDefender()) },
IntegrationLoader("FactionsUUID") { AntigriefManager.register(AntigriefFactionsUUID()) },
IntegrationLoader("Towny") { AntigriefManager.register(AntigriefTowny()) },
IntegrationLoader("Lands") { AntigriefManager.register(AntigriefLands(this)) },
@@ -135,13 +150,15 @@ abstract class EcoSpigotPlugin : EcoPlugin(
// Custom Items
IntegrationLoader("Oraxen") { CustomItemsManager.register(CustomItemsOraxen()) },
IntegrationLoader("ItemsAdder") { CustomItemsManager.register(CustomItemsItemsAdder(this)) },
IntegrationLoader("ItemsAdder") { CustomItemsManager.register(CustomItemsItemsAdder()) },
IntegrationLoader("HeadDatabase") { CustomItemsManager.register(CustomItemsHeadDatabase(this)) },
// Shop
IntegrationLoader("ShopGUIPlus") { ShopManager.register(ShopShopGuiPlus()) },
// Misc
IntegrationLoader("mcMMO") { McmmoManager.register(McmmoIntegrationImpl()) }
IntegrationLoader("mcMMO") { McmmoManager.register(McmmoIntegrationImpl()) },
IntegrationLoader("Multiverse-Inventories") { this.eventManager.registerListener(MultiverseInventoriesIntegration(this)) }
)
}
@@ -160,7 +177,6 @@ abstract class EcoSpigotPlugin : EcoPlugin(
return listOf(
NaturalExpGainListeners(),
ArmorListener(),
DispenserArmorListener(),
EntityDeathByEntityListeners(this),
ShapedRecipeListener(this),
PlayerJumpListeners(),

View File

@@ -13,7 +13,7 @@ import org.bukkit.entity.Player
class PacketChat(plugin: EcoPlugin) :
AbstractPacketAdapter(plugin,
PacketType.Play.Server.CHAT,
if (plugin.configYml.getBool("use-lower-protocollib-priority")) ListenerPriority.NORMAL else ListenerPriority.MONITOR,
if (plugin.configYml.getBool("use-lower-protocollib-priority")) ListenerPriority.NORMAL else ListenerPriority.HIGHEST,
true) {
override fun onSend(
packet: PacketContainer,

View File

@@ -6,9 +6,11 @@ import com.comphenix.protocol.events.PacketEvent
import com.willfp.eco.core.AbstractPacketAdapter
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.display.Display
import com.willfp.eco.core.fast.FastItemStack
import com.willfp.eco.spigot.display.frame.DisplayFrame
import com.willfp.eco.spigot.display.frame.lastDisplayFrame
import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack
import java.util.function.Consumer
class PacketWindowItems(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, PacketType.Play.Server.WINDOW_ITEMS, false) {
override fun onSend(
@@ -16,15 +18,36 @@ class PacketWindowItems(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, Packe
player: Player,
event: PacketEvent
) {
val windowId = packet.integers.read(0)
if (windowId != 0) {
player.lastDisplayFrame = DisplayFrame.EMPTY
}
packet.itemListModifier.modify(0) { itemStacks: List<ItemStack>? ->
if (itemStacks == null) {
return@modify null
}
itemStacks.forEach(Consumer { item: ItemStack ->
Display.display(
item, player
)
})
if (this.getPlugin().configYml.getBool("use-display-frame") && windowId == 0) {
val frameMap = mutableMapOf<Byte, Int>()
for (index in itemStacks.indices) {
frameMap[index.toByte()] = FastItemStack.wrap(itemStacks[index]).hashCode()
}
val newFrame = DisplayFrame(frameMap)
val changes = player.lastDisplayFrame.getChangedSlots(newFrame)
player.lastDisplayFrame = newFrame
for (index in changes) {
Display.display(itemStacks[index.toInt()], player)
}
} else {
itemStacks.forEach { Display.display(it, player) }
}
itemStacks
}
}

View File

@@ -0,0 +1,37 @@
package com.willfp.eco.spigot.display.frame
import org.bukkit.entity.Player
import java.util.*
import java.util.concurrent.ConcurrentHashMap
data class DisplayFrame(val items: Map<Byte, Int>) {
fun getChangedSlots(newFrame: DisplayFrame): List<Byte> {
val changes = mutableListOf<Byte>()
for ((slot, hash) in newFrame.items) {
if (items[slot] != hash) {
changes.add(slot)
}
}
return changes
}
companion object {
val EMPTY = DisplayFrame(emptyMap())
}
}
private val frames = ConcurrentHashMap<UUID, DisplayFrame>()
var Player.lastDisplayFrame: DisplayFrame
get() {
return frames[this.uniqueId] ?: DisplayFrame.EMPTY
}
set(value) {
frames[this.uniqueId] = value
}
fun clearFrames() {
frames.clear()
}

View File

@@ -0,0 +1,33 @@
package com.willfp.eco.spigot.eventlisteners.armor
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.events.ArmorChangeEvent
import com.willfp.eco.core.events.ArmorEquipEvent
import org.bukkit.Bukkit
import org.bukkit.entity.Player
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.block.BlockDispenseArmorEvent
class ArmorChangeEventListeners(
private val plugin: EcoPlugin
) : Listener {
@EventHandler
fun onArmorChange(event: ArmorEquipEvent) {
val player = event.player
val before = player.inventory.armorContents.toMutableList()
plugin.scheduler.run {
val after = player.inventory.armorContents.toMutableList()
val armorChangeEvent = ArmorChangeEvent(player, before, after)
Bukkit.getPluginManager().callEvent(armorChangeEvent)
}
}
@EventHandler
fun dispenseArmorEvent(event: BlockDispenseArmorEvent) {
val type = ArmorType.matchType(event.item)
if (type != null && event.targetEntity is Player) {
Bukkit.getPluginManager().callEvent(ArmorEquipEvent(event.targetEntity as Player))
}
}
}

View File

@@ -0,0 +1,175 @@
package com.willfp.eco.spigot.eventlisteners.armor
import com.willfp.eco.core.events.ArmorEquipEvent
import org.bukkit.Bukkit
import org.bukkit.Material
import org.bukkit.entity.Player
import org.bukkit.event.Event
import org.bukkit.event.EventHandler
import org.bukkit.event.EventPriority
import org.bukkit.event.Listener
import org.bukkit.event.block.Action
import org.bukkit.event.entity.PlayerDeathEvent
import org.bukkit.event.inventory.*
import org.bukkit.event.player.PlayerInteractEvent
import org.bukkit.event.player.PlayerItemBreakEvent
import org.bukkit.event.player.PlayerJoinEvent
import org.bukkit.event.player.PlayerRespawnEvent
import org.bukkit.inventory.ItemStack
class ArmorListener : Listener {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
fun inventoryClick(event: InventoryClickEvent) {
var shift = false
var numberkey = false
if (event.isCancelled) {
return
}
if (event.action == InventoryAction.NOTHING) {
return
}
if (event.click == ClickType.SHIFT_LEFT || event.click == ClickType.SHIFT_RIGHT) {
shift = true
}
if (event.click == ClickType.NUMBER_KEY) {
numberkey = true
}
if (event.slotType != InventoryType.SlotType.ARMOR && event.slotType != InventoryType.SlotType.QUICKBAR && event.slotType != InventoryType.SlotType.CONTAINER) {
return
}
if (event.clickedInventory != null && event.clickedInventory!!.type != InventoryType.PLAYER) {
return
}
if (event.inventory.type != InventoryType.CRAFTING && event.inventory.type != InventoryType.PLAYER) {
return
}
if (event.whoClicked !is Player) {
return
}
var newArmorType = ArmorType.matchType(if (shift) event.currentItem else event.cursor)
if (!shift && newArmorType != null && event.rawSlot != newArmorType.slot) {
// Used for drag and drop checking to make sure you aren't trying to place a helmet in the boots slot.
return
}
if (shift) {
newArmorType = ArmorType.matchType(event.currentItem)
if (newArmorType != null) {
var equipping = true
if (event.rawSlot == newArmorType.slot) {
equipping = false
}
if (newArmorType == ArmorType.HELMET && equipping == isAirOrNull(event.whoClicked.inventory.helmet) || newArmorType == ArmorType.CHESTPLATE && equipping == isAirOrNull(
event.whoClicked.inventory.chestplate
) || newArmorType == ArmorType.LEGGINGS && equipping == isAirOrNull(event.whoClicked.inventory.leggings) || newArmorType == ArmorType.BOOTS && equipping == isAirOrNull(
event.whoClicked.inventory.boots
)
) {
val armorEquipEvent = ArmorEquipEvent(
(event.whoClicked as Player)
)
Bukkit.getPluginManager().callEvent(armorEquipEvent)
}
}
} else {
if (numberkey) {
if (event.clickedInventory!!.type == InventoryType.PLAYER) {
val hotbarItem = event.clickedInventory!!.getItem(event.hotbarButton)
newArmorType = if (!isAirOrNull(hotbarItem)) {
ArmorType.matchType(hotbarItem)
} else {
ArmorType.matchType(if (!isAirOrNull(event.currentItem)) event.currentItem else event.cursor)
}
}
} else {
if (isAirOrNull(event.cursor) && !isAirOrNull(event.currentItem)) {
newArmorType = ArmorType.matchType(event.currentItem)
}
}
if (newArmorType != null && event.rawSlot == newArmorType.slot) {
val armorEquipEvent = ArmorEquipEvent(
(event.whoClicked as Player)
)
Bukkit.getPluginManager().callEvent(armorEquipEvent)
}
}
}
@EventHandler(priority = EventPriority.HIGHEST)
fun playerInteractEvent(e: PlayerInteractEvent) {
if (e.useItemInHand() == Event.Result.DENY) {
return
}
if (e.action == Action.PHYSICAL) {
return
}
if (e.action == Action.RIGHT_CLICK_AIR || e.action == Action.RIGHT_CLICK_BLOCK) {
val newArmorType = ArmorType.matchType(e.item)
if (newArmorType != null) {
if (newArmorType == ArmorType.HELMET && isAirOrNull(e.player.inventory.helmet) || newArmorType == ArmorType.CHESTPLATE && isAirOrNull(
e.player.inventory.chestplate
) || newArmorType == ArmorType.LEGGINGS && isAirOrNull(e.player.inventory.leggings) || newArmorType == ArmorType.BOOTS && isAirOrNull(
e.player.inventory.boots
)
) {
val armorEquipEvent = ArmorEquipEvent(e.player)
Bukkit.getPluginManager().callEvent(armorEquipEvent)
}
}
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
fun inventoryDrag(event: InventoryDragEvent) {
val type = ArmorType.matchType(event.oldCursor)
if (event.rawSlots.isEmpty()) {
return
}
if (type != null && type.slot == event.rawSlots.stream().findFirst().orElse(0)) {
val armorEquipEvent = ArmorEquipEvent(
(event.whoClicked as Player)
)
Bukkit.getPluginManager().callEvent(armorEquipEvent)
}
}
@EventHandler
fun playerJoinEvent(event: PlayerJoinEvent) {
val armorEquipEvent = ArmorEquipEvent(event.player)
Bukkit.getPluginManager().callEvent(armorEquipEvent)
}
@EventHandler
fun playerRespawnEvent(event: PlayerRespawnEvent) {
val armorEquipEvent = ArmorEquipEvent(event.player)
Bukkit.getPluginManager().callEvent(armorEquipEvent)
}
@EventHandler
fun itemBreakEvent(event: PlayerItemBreakEvent) {
val type = ArmorType.matchType(event.brokenItem)
if (type != null) {
val p = event.player
val armorEquipEvent = ArmorEquipEvent(p)
Bukkit.getPluginManager().callEvent(armorEquipEvent)
}
}
@EventHandler
fun playerDeathEvent(event: PlayerDeathEvent) {
val p = event.entity
if (event.keepInventory) {
return
}
for (i in p.inventory.armorContents) {
if (!isAirOrNull(i)) {
Bukkit.getPluginManager().callEvent(ArmorEquipEvent(p))
}
}
}
companion object {
fun isAirOrNull(item: ItemStack?): Boolean {
return item == null || item.type == Material.AIR
}
}
}

View File

@@ -0,0 +1,27 @@
package com.willfp.eco.spigot.eventlisteners.armor
import org.bukkit.inventory.ItemStack
enum class ArmorType(val slot: Int) {
HELMET(5), CHESTPLATE(6), LEGGINGS(7), BOOTS(8);
companion object {
fun matchType(itemStack: ItemStack?): ArmorType? {
if (ArmorListener.isAirOrNull(itemStack)) {
return null
}
itemStack ?: return null
val type = itemStack.type.name
return if (type.endsWith("_HELMET") || type.endsWith("_SKULL") || type.endsWith("PLAYER_HEAD")) {
HELMET
} else if (type.endsWith("_CHESTPLATE") || type.endsWith("ELYTRA")) {
CHESTPLATE
} else if (type.endsWith("_LEGGINGS")) {
LEGGINGS
} else if (type.endsWith("_BOOTS")) {
BOOTS
} else {
null
}
}
}
}

View File

@@ -59,4 +59,15 @@ class AntigriefCombatLogXV10 : AntigriefWrapper {
return "CombatLogX"
}
override fun equals(other: Any?): Boolean {
if (other !is AntigriefWrapper) {
return false
}
return other.pluginName == this.pluginName
}
override fun hashCode(): Int {
return this.pluginName.hashCode()
}
}

View File

@@ -62,4 +62,15 @@ class AntigriefCombatLogXV11 : AntigriefWrapper {
return "CombatLogX"
}
override fun equals(other: Any?): Boolean {
if (other !is AntigriefWrapper) {
return false
}
return other.pluginName == this.pluginName
}
override fun hashCode(): Int {
return this.pluginName.hashCode()
}
}

View File

@@ -64,4 +64,16 @@ class AntigriefFactionsUUID : AntigriefWrapper {
override fun getPluginName(): String {
return "FactionsUUID"
}
override fun equals(other: Any?): Boolean {
if (other !is AntigriefWrapper) {
return false
}
return other.pluginName == this.pluginName
}
override fun hashCode(): Int {
return this.pluginName.hashCode()
}
}

View File

@@ -1,81 +0,0 @@
package com.willfp.eco.spigot.integrations.antigrief
import com.flowpowered.math.vector.Vector3i
import com.griefdefender.api.GriefDefender
import com.griefdefender.api.data.PlayerData
import com.griefdefender.api.permission.flag.Flags
import com.willfp.eco.core.integrations.antigrief.AntigriefWrapper
import org.bukkit.Location
import org.bukkit.block.Block
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Player
import java.util.*
class AntigriefGriefDefender : AntigriefWrapper {
override fun canBreakBlock(player: Player, block: Block): Boolean {
val data = GriefDefender.getCore().getPlayerData(player.world.uid, player.uniqueId) ?: return true
val claim = GriefDefender.getCore().getClaimAt(Vector3i(block.location.x, block.location.y, block.location.z))
?: return true
return if (data.canIgnoreClaim(claim)) {
true
} else {
claim.getActiveFlagPermissionValue(Flags.BLOCK_BREAK, data.user, Collections.emptySet(), true).asBoolean()
}
}
override fun canCreateExplosion(player: Player, location: Location): Boolean {
val data = GriefDefender.getCore().getPlayerData(player.world.uid, player.uniqueId) ?: return true
val claim = GriefDefender.getCore().getClaimAt(Vector3i(location.x, location.y, location.z)) ?: return true
return if (data.canIgnoreClaim(claim)) {
true
} else {
claim.getActiveFlagPermissionValue(Flags.EXPLOSION_BLOCK, data.user, Collections.emptySet(), true)
.asBoolean()
}
}
override fun canPlaceBlock(player: Player, block: Block): Boolean {
val data: PlayerData = GriefDefender.getCore().getPlayerData(player.world.uid, player.uniqueId) ?: return true
val claim =
GriefDefender.getCore().getClaimAt(Vector3i(block.location.x, block.location.y, block.location.z))
?: return true
return if (data.canIgnoreClaim(claim)) {
true
} else {
claim.getActiveFlagPermissionValue(Flags.BLOCK_PLACE, data.user, Collections.emptySet(), true)
.asBoolean()
}
}
override fun canInjure(player: Player, victim: LivingEntity): Boolean {
val data = GriefDefender.getCore().getPlayerData(player.world.uid, player.uniqueId) ?: return true
if (data.canIgnoreClaim(data.currentClaim)) {
return true
}
return if (victim is Player) {
val vicData = GriefDefender.getCore().getPlayerData(victim.world.uid, victim.uniqueId)
if (vicData != null) {
data.canPvp(data.currentClaim) && data.canPvp(vicData.currentClaim)
} else data.canPvp(data.currentClaim)
} else {
val claim =
GriefDefender.getCore().getClaimAt(Vector3i(victim.location.x, victim.location.y, victim.location.z))
claim?.getActiveFlagPermissionValue(Flags.ENTITY_DAMAGE, data.user, Collections.emptySet(), true)
?.asBoolean() ?: true
}
}
override fun getPluginName(): String {
return "GriefDefender"
}
}

View File

@@ -54,4 +54,16 @@ class AntigriefGriefPrevention : AntigriefWrapper {
override fun getPluginName(): String {
return "GriefPrevention"
}
override fun equals(other: Any?): Boolean {
if (other !is AntigriefWrapper) {
return false
}
return other.pluginName == this.pluginName
}
override fun hashCode(): Int {
return this.pluginName.hashCode()
}
}

View File

@@ -68,4 +68,16 @@ class AntigriefKingdoms : AntigriefWrapper {
override fun getPluginName(): String {
return "Kingdoms"
}
override fun equals(other: Any?): Boolean {
if (other !is AntigriefWrapper) {
return false
}
return other.pluginName == this.pluginName
}
override fun hashCode(): Int {
return this.pluginName.hashCode()
}
}

View File

@@ -55,4 +55,16 @@ class AntigriefLands(private val plugin: EcoPlugin) : AntigriefWrapper {
override fun getPluginName(): String {
return "Lands"
}
override fun equals(other: Any?): Boolean {
if (other !is AntigriefWrapper) {
return false
}
return other.pluginName == this.pluginName
}
override fun hashCode(): Int {
return this.pluginName.hashCode()
}
}

View File

@@ -72,4 +72,16 @@ class AntigriefTowny : AntigriefWrapper {
override fun getPluginName(): String {
return "Towny"
}
override fun equals(other: Any?): Boolean {
if (other !is AntigriefWrapper) {
return false
}
return other.pluginName == this.pluginName
}
override fun hashCode(): Int {
return this.pluginName.hashCode()
}
}

View File

@@ -101,4 +101,16 @@ class AntigriefWorldGuard : AntigriefWrapper {
override fun getPluginName(): String {
return "WorldGuard"
}
override fun equals(other: Any?): Boolean {
if (other !is AntigriefWrapper) {
return false
}
return other.pluginName == this.pluginName
}
override fun hashCode(): Int {
return this.pluginName.hashCode()
}
}

View File

@@ -0,0 +1,58 @@
package com.willfp.eco.spigot.integrations.customitems
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.integrations.customitems.CustomItemsWrapper
import com.willfp.eco.core.items.CustomItem
import com.willfp.eco.core.items.Items
import com.willfp.eco.core.items.TestableItem
import com.willfp.eco.core.items.provider.ItemProvider
import com.willfp.eco.util.NamespacedKeyUtils
import me.arcaniax.hdb.api.DatabaseLoadEvent
import me.arcaniax.hdb.api.HeadDatabaseAPI
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.inventory.ItemStack
import java.util.function.Predicate
class CustomItemsHeadDatabase(
plugin: EcoPlugin
) : CustomItemsWrapper {
private val provider = HeadDBProvider()
init {
plugin.eventManager.registerListener(provider)
}
override fun registerAllItems() {
Items.registerItemProvider(HeadDBProvider())
}
override fun getPluginName(): String {
return "HeadDatabase"
}
private inner class HeadDBProvider : ItemProvider("headdb"), Listener {
private lateinit var api: HeadDatabaseAPI
override fun provideForKey(key: String): TestableItem? {
if (this::api.isInitialized) {
return null
}
val head = api.getItemHead(key) ?: return null
val namespacedKey = NamespacedKeyUtils.create("headdb", key)
return CustomItem(
namespacedKey,
Predicate { test: ItemStack ->
val found = api.getItemID(test) ?: return@Predicate false
found == key
},
head
)
}
@EventHandler
fun onLoad(@Suppress("UNUSED_PARAMETER") event: DatabaseLoadEvent) {
api = HeadDatabaseAPI()
}
}
}

View File

@@ -1,36 +1,39 @@
package com.willfp.eco.spigot.integrations.customitems
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.integrations.customitems.CustomItemsWrapper
import com.willfp.eco.core.items.CustomItem
import com.willfp.eco.core.items.Items
import com.willfp.eco.core.items.TestableItem
import com.willfp.eco.core.items.provider.ItemProvider
import com.willfp.eco.util.NamespacedKeyUtils
import dev.lone.itemsadder.api.CustomStack
import dev.lone.itemsadder.api.ItemsAdder
import org.bukkit.inventory.ItemStack
import java.util.function.Predicate
class CustomItemsItemsAdder(
private val plugin: EcoPlugin
) : CustomItemsWrapper {
class CustomItemsItemsAdder : CustomItemsWrapper {
override fun registerAllItems() {
plugin.scheduler.runLater({
for (item in ItemsAdder.getAllItems()) {
val stack = item.itemStack
val id = item.id
val key = NamespacedKeyUtils.create("itemsadder", id.lowercase())
CustomItem(
key,
Predicate { test: ItemStack ->
val customStack = CustomStack.byItemStack(test) ?: return@Predicate false
customStack.id.equals(id, ignoreCase = true)
},
stack
).register()
}
}, 2)
Items.registerItemProvider(ItemsAdderProvider())
}
override fun getPluginName(): String {
return "ItemsAdder"
}
private class ItemsAdderProvider : ItemProvider("itemsadder") {
override fun provideForKey(key: String): TestableItem? {
val item = CustomStack.getInstance("itemsadder:$key") ?: return null
val id = item.id
val namespacedKey = NamespacedKeyUtils.create("itemsadder", key)
val stack = item.itemStack
return CustomItem(
namespacedKey,
Predicate { test: ItemStack ->
val customStack = CustomStack.byItemStack(test) ?: return@Predicate false
customStack.id.equals(id, ignoreCase = true)
},
stack
)
}
}
}

View File

@@ -14,7 +14,9 @@ class CustomItemsOraxen : CustomItemsWrapper {
for (item in OraxenItems.getItems()) {
val stack = item.build()
val id: String = Objects.requireNonNullElse(OraxenItems.getIdByItem(item), "")
if (id.isEmpty()) continue
if (id.isEmpty()) {
continue
}
val key: NamespacedKey = NamespacedKeyUtils.create("oraxen", id.lowercase())
CustomItem(
key, Predicate { test: ItemStack ->

View File

@@ -0,0 +1,21 @@
package com.willfp.eco.spigot.integrations.multiverseinventories
import com.onarandombox.multiverseinventories.event.WorldChangeShareHandlingEvent
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.events.ArmorChangeEvent
import org.bukkit.Bukkit
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
class MultiverseInventoriesIntegration(
private val plugin: EcoPlugin
): Listener {
@EventHandler
fun onWorldChange(event: WorldChangeShareHandlingEvent) {
val before = event.player.inventory.armorContents.toMutableList()
this.plugin.scheduler.run {
val after = event.player.inventory.armorContents.toMutableList()
Bukkit.getPluginManager().callEvent(ArmorChangeEvent(event.player, before, after))
}
}
}

View File

@@ -19,4 +19,13 @@ enable-bstats: true
# Some plugins use their own item display systems (eg Triton)
# And must be ran after eco. Don't enable this unless you run a conflicting plugin
# and have been told to enable it.
use-lower-protocollib-priority: false
use-lower-protocollib-priority: false
# Display frames massively optimize PacketWindowItems, however some users have
# reported display bugs by using it. If you have any problems with it, then you
# should disable this option.
use-display-frame: true
# Time to live for a display frame. In other words, this is how frequent (in ticks)
# that display frames will be cleared / deleted.
display-frame-ttl: 17

View File

@@ -25,8 +25,12 @@ softdepend:
- ItemsAdder
- Oraxen
- HeadDatabase
- GriefDefender
- Multiverse-Inventories
libraries:
- org.reflections:reflections:0.9.12
- org.apache.maven:maven-artifact:3.0.3
- org.jetbrains.kotlin:kotlin-stdlib:1.5.31
- 'org.reflections:reflections:0.9.12'
- 'org.apache.maven:maven-artifact:3.0.3'
- 'org.jetbrains.kotlin:kotlin-stdlib:1.5.31'
- 'net.kyori:adventure-platform-bukkit:4.0.0'
- 'net.kyori:adventure-api:4.9.1'
- 'net.kyori:adventure-text-serializer-gson:4.9.2'
- 'net.kyori:adventure-text-serializer-legacy:4.8.1'

View File

@@ -7,5 +7,5 @@ interface ChatComponentProxy : AbstractProxy {
fun modifyComponent(
obj: Any,
player: Player
): Any?
): Any
}

View File

@@ -1,2 +1,2 @@
version = 6.9.1
version = 6.11.0
plugin-name = eco

Binary file not shown.