Compare commits
102 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5c29859d49 | ||
|
|
02510127d1 | ||
|
|
f6b5c8f7e0 | ||
|
|
dbfef3094b | ||
|
|
b5c3af752c | ||
|
|
d0366b39e2 | ||
|
|
ed5390d2b5 | ||
|
|
e31857a15d | ||
|
|
32e119d187 | ||
|
|
5690eccd14 | ||
|
|
2faf3732df | ||
|
|
8670fb36e0 | ||
|
|
7c001c4809 | ||
|
|
bce1dd9fee | ||
|
|
412c2e1e3c | ||
|
|
dd7ffac974 | ||
|
|
7ad59e0166 | ||
|
|
2f2bdbb9f5 | ||
|
|
d23dc10bc5 | ||
|
|
46c2e3f90a | ||
|
|
1776b668a4 | ||
|
|
10dccd0f38 | ||
|
|
f1918eb1ec | ||
|
|
436b33fde2 | ||
|
|
cfa5cab1fa | ||
|
|
a8ba4dd812 | ||
|
|
94bf383d23 | ||
|
|
096207de82 | ||
|
|
3cb654f5df | ||
|
|
5552cc4fb0 | ||
|
|
94aacf8cca | ||
|
|
128d473b33 | ||
|
|
d5679dd58f | ||
|
|
b1e8165ecb | ||
|
|
d0a3d644f3 | ||
|
|
35b060af53 | ||
|
|
337dba23b4 | ||
|
|
433f9f53ab | ||
|
|
ba7a748efd | ||
|
|
1365fdae88 | ||
|
|
6a159bf049 | ||
|
|
31e0e93951 | ||
|
|
876343facb | ||
|
|
f0cd9ae16d | ||
|
|
b220428b8c | ||
|
|
8386aacfd8 | ||
|
|
3c54e24102 | ||
|
|
3dc0693b8c | ||
|
|
f087113ddf | ||
|
|
d5d1f5d8cc | ||
|
|
0d5bf901e2 | ||
|
|
ae0445f47b | ||
|
|
a6ba24b7a5 | ||
|
|
1b00831147 | ||
|
|
479cff60d5 | ||
|
|
d2499b1e27 | ||
|
|
4f65f33953 | ||
|
|
6d4a69c781 | ||
|
|
e90e58b50a | ||
|
|
826bdb63d0 | ||
|
|
4ecba69161 | ||
|
|
e64510ebf5 | ||
|
|
50a506af62 | ||
|
|
bdbbb7e40a | ||
|
|
f2503e989c | ||
|
|
11c54a0055 | ||
|
|
7cc24199fb | ||
|
|
068b2cca0c | ||
|
|
f67f01278e | ||
|
|
8be8e1dab2 | ||
|
|
6d3651aca1 | ||
|
|
3dd2c58595 | ||
|
|
255aa1dd54 | ||
|
|
f2c5b085e8 | ||
|
|
b8a5fe0031 | ||
|
|
5603890663 | ||
|
|
1a86cc4dbd | ||
|
|
734add6dbc | ||
|
|
5641c0def3 | ||
|
|
b74ab5349a | ||
|
|
b0971e5124 | ||
|
|
02d8c8c6b6 | ||
|
|
d9bd5257e3 | ||
|
|
c1a214f34e | ||
|
|
64d1fbb9b1 | ||
|
|
a5433fbb3f | ||
|
|
2a2aed52e0 | ||
|
|
b16266e22a | ||
|
|
2c886dc33b | ||
|
|
db9c60cf35 | ||
|
|
a34b36daec | ||
|
|
41a35e99fd | ||
|
|
8e12dad247 | ||
|
|
72afa1e5cc | ||
|
|
9904553325 | ||
|
|
ad069ab32f | ||
|
|
b83a3dd548 | ||
|
|
7f41eab5e4 | ||
|
|
0d1c2364da | ||
|
|
5bca33a9f5 | ||
|
|
1196fe8004 | ||
|
|
98ae416fa7 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -14,7 +14,7 @@ bin/
|
|||||||
# Gradle
|
# Gradle
|
||||||
.gradle
|
.gradle
|
||||||
**/build/
|
**/build/
|
||||||
!src/**/build/
|
!eco-util/src/**/build/
|
||||||
.gradletasknamecache
|
.gradletasknamecache
|
||||||
!gradle-wrapper.jar
|
!gradle-wrapper.jar
|
||||||
gradle-app.setting
|
gradle-app.setting
|
||||||
|
|||||||
85
build.gradle
85
build.gradle
@@ -6,31 +6,17 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'org.apache.maven:maven-artifact:3.0.3'
|
implementation project(":eco-util")
|
||||||
implementation 'org.bstats:bstats-bukkit:1.7'
|
implementation project(":eco-core").getSubprojects()
|
||||||
compileOnly 'org.spigotmc:spigot-api:1.16.4-R0.1-SNAPSHOT'
|
|
||||||
compileOnly 'me.clip:placeholderapi:2.10.9'
|
|
||||||
compileOnly 'com.comphenix.protocol:ProtocolLib:4.6.0-SNAPSHOT'
|
|
||||||
compileOnly 'com.sk89q.worldguard:worldguard-bukkit:7.0.4-SNAPSHOT'
|
|
||||||
compileOnly 'com.github.TechFortress:GriefPrevention:16.14.0'
|
|
||||||
compileOnly 'com.massivecraft:Factions:1.6.9.5-U0.5.10'
|
|
||||||
compileOnly 'com.github.cryptomorin:kingdoms:1.10.3.1'
|
|
||||||
compileOnly 'com.github.TownyAdvanced:Towny:0.96.2.0'
|
|
||||||
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 'org.jetbrains:annotations:19.0.0'
|
|
||||||
compileOnly fileTree(dir: '/lib', include: ['*.jar'])
|
|
||||||
|
|
||||||
// Lombok
|
|
||||||
compileOnly 'org.projectlombok:lombok:1.18.16'
|
|
||||||
annotationProcessor 'org.projectlombok:lombok:1.18.16'
|
|
||||||
testCompileOnly 'org.projectlombok:lombok:1.18.16'
|
|
||||||
testAnnotationProcessor 'org.projectlombok:lombok:1.18.16'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
apply plugin: 'java'
|
||||||
|
apply plugin: 'java-library'
|
||||||
|
apply plugin: 'maven-publish'
|
||||||
|
apply plugin: 'com.github.johnrengelman.shadow'
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
jcenter()
|
jcenter()
|
||||||
mavenLocal()
|
mavenLocal()
|
||||||
@@ -39,7 +25,7 @@ repositories {
|
|||||||
// NMS (for jitpack compilation)
|
// NMS (for jitpack compilation)
|
||||||
maven { url 'https://repo.codemc.org/repository/nms/' }
|
maven { url 'https://repo.codemc.org/repository/nms/' }
|
||||||
|
|
||||||
// bStats
|
// bStats, mcMMO
|
||||||
maven { url 'https://repo.codemc.org/repository/maven-public' }
|
maven { url 'https://repo.codemc.org/repository/maven-public' }
|
||||||
|
|
||||||
// Spigot API
|
// Spigot API
|
||||||
@@ -59,44 +45,53 @@ repositories {
|
|||||||
|
|
||||||
// NoCheatPlus
|
// NoCheatPlus
|
||||||
maven { url 'https://repo.md-5.net/content/repositories/snapshots/' }
|
maven { url 'https://repo.md-5.net/content/repositories/snapshots/' }
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType(JavaCompile) {
|
dependencies {
|
||||||
|
compileOnly 'org.spigotmc:spigot-api:1.16.4-R0.1-SNAPSHOT'
|
||||||
|
compileOnly 'org.jetbrains:annotations:19.0.0'
|
||||||
|
|
||||||
|
// Lombok
|
||||||
|
compileOnly 'org.projectlombok:lombok:1.18.16'
|
||||||
|
annotationProcessor 'org.projectlombok:lombok:1.18.16'
|
||||||
|
testCompileOnly 'org.projectlombok:lombok:1.18.16'
|
||||||
|
testAnnotationProcessor 'org.projectlombok:lombok:1.18.16'
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType(JavaCompile) {
|
||||||
options.deprecation = true
|
options.deprecation = true
|
||||||
options.encoding = 'UTF-8'
|
options.encoding = 'UTF-8'
|
||||||
}
|
}
|
||||||
|
|
||||||
configurations.all {
|
configurations.all {
|
||||||
exclude group: "org.codehaus.plexus", module: "plexus-utils"
|
exclude group: "org.codehaus.plexus", module: "plexus-utils"
|
||||||
exclude group: "com.mojang", module: "brigadier"
|
exclude group: "com.mojang", module: "brigadier"
|
||||||
exclude group: "org.kitteh", module: "paste-gg-api"
|
exclude group: "org.kitteh", module: "paste-gg-api"
|
||||||
exclude group: "org.spongepowered", module: "configurate-hocon"
|
exclude group: "org.spongepowered", module: "configurate-hocon"
|
||||||
exclude group: "com.darkblade12", module: "particleeffect"
|
exclude group: "com.darkblade12", module: "particleeffect"
|
||||||
}
|
exclude group: "com.github.cryptomorin", module: "XSeries"
|
||||||
|
}
|
||||||
|
|
||||||
shadowJar {
|
shadowJar {
|
||||||
relocate('org.bstats.bukkit', 'com.willfp.eco.util.shaded.bstats')
|
relocate('org.bstats.bukkit', 'com.willfp.eco.util.shaded.bstats')
|
||||||
relocate('org.apache.maven', 'com.willfp.eco.util.shaded.maven')
|
relocate('org.apache.maven', 'com.willfp.eco.util.shaded.maven')
|
||||||
}
|
|
||||||
|
|
||||||
publishing {
|
|
||||||
publications {
|
|
||||||
shadow(MavenPublication) {
|
|
||||||
from components.java
|
|
||||||
artifact shadowJar
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jar {
|
||||||
|
onlyIf { !sourceSets.main.allSource.files.isEmpty() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compileJava {
|
||||||
|
onlyIf { !sourceSets.main.allSource.files.isEmpty() }
|
||||||
|
}
|
||||||
|
|
||||||
|
compileJava.options.encoding = 'UTF-8'
|
||||||
|
compileJava.dependsOn clean
|
||||||
|
|
||||||
|
build.dependsOn shadowJar
|
||||||
}
|
}
|
||||||
|
|
||||||
compileJava.options.encoding = 'UTF-8'
|
|
||||||
compileJava.dependsOn clean
|
|
||||||
|
|
||||||
publishToMavenLocal.dependsOn shadowJar
|
|
||||||
|
|
||||||
build.dependsOn shadowJar
|
|
||||||
build.dependsOn publishToMavenLocal
|
|
||||||
|
|
||||||
group = 'com.willfp'
|
group = 'com.willfp'
|
||||||
archivesBaseName = project.name
|
archivesBaseName = project.name
|
||||||
version = '1.0.1'
|
version = findProperty("version")
|
||||||
java.sourceCompatibility = JavaVersion.VERSION_1_8
|
java.sourceCompatibility = JavaVersion.VERSION_1_8
|
||||||
@@ -115,7 +115,6 @@
|
|||||||
<!-- Checks for imports -->
|
<!-- Checks for imports -->
|
||||||
<!-- See https://checkstyle.org/config_imports.html -->
|
<!-- See https://checkstyle.org/config_imports.html -->
|
||||||
<module name="AvoidStarImport"/>
|
<module name="AvoidStarImport"/>
|
||||||
<module name="IllegalImport"/> <!-- defaults to sun.* packages -->
|
|
||||||
<module name="RedundantImport"/>
|
<module name="RedundantImport"/>
|
||||||
<module name="UnusedImports">
|
<module name="UnusedImports">
|
||||||
<property name="processJavadoc" value="true"/>
|
<property name="processJavadoc" value="true"/>
|
||||||
|
|||||||
8
eco-core/build.gradle
Normal file
8
eco-core/build.gradle
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
group 'com.willfp'
|
||||||
|
version rootProject.version
|
||||||
|
|
||||||
|
subprojects {
|
||||||
|
dependencies {
|
||||||
|
compileOnly project(":eco-util")
|
||||||
|
}
|
||||||
|
}
|
||||||
9
eco-core/core-nms/build.gradle
Normal file
9
eco-core/core-nms/build.gradle
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
group 'com.willfp'
|
||||||
|
version rootProject.version
|
||||||
|
|
||||||
|
subprojects {
|
||||||
|
dependencies {
|
||||||
|
compileOnly project(':eco-core:core-proxy')
|
||||||
|
compileOnly project(':eco-core:core-plugin')
|
||||||
|
}
|
||||||
|
}
|
||||||
6
eco-core/core-nms/v1_15_R1/build.gradle
Normal file
6
eco-core/core-nms/v1_15_R1/build.gradle
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
group 'com.willfp'
|
||||||
|
version rootProject.version
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compileOnly 'org.spigotmc:spigot:1.15.2-R0.1-SNAPSHOT'
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.willfp.eco.proxy.v1_15_R1;
|
||||||
|
|
||||||
|
import com.willfp.eco.proxy.proxies.AutoCraftProxy;
|
||||||
|
import net.minecraft.server.v1_15_R1.MinecraftKey;
|
||||||
|
import net.minecraft.server.v1_15_R1.PacketPlayOutAutoRecipe;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
public final class AutoCraft implements AutoCraftProxy {
|
||||||
|
@Override
|
||||||
|
public void modifyPacket(@NotNull final Object packet) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
PacketPlayOutAutoRecipe recipePacket = (PacketPlayOutAutoRecipe) packet;
|
||||||
|
Field fKey = recipePacket.getClass().getDeclaredField("b");
|
||||||
|
fKey.setAccessible(true);
|
||||||
|
MinecraftKey key = (MinecraftKey) fKey.get(recipePacket);
|
||||||
|
fKey.set(recipePacket, new MinecraftKey(key.getNamespace(), key.getKey() + "_displayed"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.willfp.eco.proxy.v1_15_R1;
|
||||||
|
|
||||||
|
import com.willfp.eco.proxy.proxies.ChatComponentProxy;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public final class ChatComponent implements ChatComponentProxy {
|
||||||
|
@Override
|
||||||
|
public Object modifyComponent(@NotNull final Object object) {
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package com.willfp.eco.proxy.v1_15_R1;
|
||||||
|
|
||||||
|
import com.willfp.eco.proxy.proxies.VillagerTradeProxy;
|
||||||
|
import com.willfp.eco.util.display.Display;
|
||||||
|
import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack;
|
||||||
|
import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftMerchantRecipe;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.MerchantRecipe;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
public final class VillagerTrade implements VillagerTradeProxy {
|
||||||
|
@Override
|
||||||
|
public void displayTrade(@NotNull final MerchantRecipe merchantRecipe) {
|
||||||
|
try {
|
||||||
|
// Bukkit MerchantRecipe result
|
||||||
|
Field fResult = MerchantRecipe.class.getDeclaredField("result");
|
||||||
|
fResult.setAccessible(true);
|
||||||
|
|
||||||
|
ItemStack result = merchantRecipe.getResult();
|
||||||
|
Display.display(result);
|
||||||
|
fResult.set(merchantRecipe, result);
|
||||||
|
|
||||||
|
// Get NMS MerchantRecipe from CraftMerchantRecipe
|
||||||
|
Field fHandle = CraftMerchantRecipe.class.getDeclaredField("handle");
|
||||||
|
fHandle.setAccessible(true);
|
||||||
|
net.minecraft.server.v1_15_R1.MerchantRecipe handle = (net.minecraft.server.v1_15_R1.MerchantRecipe) fHandle.get(merchantRecipe); // NMS Recipe
|
||||||
|
|
||||||
|
Field fSelling = net.minecraft.server.v1_15_R1.MerchantRecipe.class.getDeclaredField("sellingItem");
|
||||||
|
fSelling.setAccessible(true);
|
||||||
|
|
||||||
|
ItemStack selling = CraftItemStack.asBukkitCopy(handle.sellingItem);
|
||||||
|
Display.display(selling);
|
||||||
|
fSelling.set(handle, CraftItemStack.asNMSCopy(selling));
|
||||||
|
} catch (IllegalAccessException | NoSuchFieldException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
6
eco-core/core-nms/v1_16_R1/build.gradle
Normal file
6
eco-core/core-nms/v1_16_R1/build.gradle
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
group 'com.willfp'
|
||||||
|
version rootProject.version
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compileOnly 'org.spigotmc:spigot:1.16.1-R0.1-SNAPSHOT'
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.willfp.eco.proxy.v1_16_R1;
|
||||||
|
|
||||||
|
import com.willfp.eco.proxy.proxies.AutoCraftProxy;
|
||||||
|
import net.minecraft.server.v1_16_R1.MinecraftKey;
|
||||||
|
import net.minecraft.server.v1_16_R1.PacketPlayOutAutoRecipe;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
public final class AutoCraft implements AutoCraftProxy {
|
||||||
|
@Override
|
||||||
|
public void modifyPacket(@NotNull final Object packet) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
PacketPlayOutAutoRecipe recipePacket = (PacketPlayOutAutoRecipe) packet;
|
||||||
|
Field fKey = recipePacket.getClass().getDeclaredField("b");
|
||||||
|
fKey.setAccessible(true);
|
||||||
|
MinecraftKey key = (MinecraftKey) fKey.get(recipePacket);
|
||||||
|
fKey.set(recipePacket, new MinecraftKey(key.getNamespace(), key.getKey() + "_displayed"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
package com.willfp.eco.proxy.v1_16_R1;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonPrimitive;
|
||||||
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
|
import com.willfp.eco.proxy.proxies.ChatComponentProxy;
|
||||||
|
import com.willfp.eco.util.display.Display;
|
||||||
|
import net.minecraft.server.v1_16_R1.ChatBaseComponent;
|
||||||
|
import net.minecraft.server.v1_16_R1.ChatHoverable;
|
||||||
|
import net.minecraft.server.v1_16_R1.ChatMessage;
|
||||||
|
import net.minecraft.server.v1_16_R1.ChatModifier;
|
||||||
|
import net.minecraft.server.v1_16_R1.IChatBaseComponent;
|
||||||
|
import net.minecraft.server.v1_16_R1.MojangsonParser;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftItemStack;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public final class ChatComponent implements ChatComponentProxy {
|
||||||
|
@Override
|
||||||
|
public Object modifyComponent(@NotNull final Object object) {
|
||||||
|
if (!(object instanceof IChatBaseComponent)) {
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
IChatBaseComponent chatComponent = (IChatBaseComponent) object;
|
||||||
|
chatComponent.stream().forEach(this::modifyBaseComponent);
|
||||||
|
|
||||||
|
return chatComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void modifyBaseComponent(@NotNull final IChatBaseComponent component) {
|
||||||
|
component.getSiblings().forEach(this::modifyBaseComponent);
|
||||||
|
if (component instanceof ChatMessage) {
|
||||||
|
Arrays.stream(((ChatMessage) component).getArgs())
|
||||||
|
.filter(o -> o instanceof IChatBaseComponent)
|
||||||
|
.map(o -> (IChatBaseComponent) o)
|
||||||
|
.forEach(this::modifyBaseComponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatHoverable hoverable = component.getChatModifier().getHoverEvent();
|
||||||
|
|
||||||
|
if (hoverable == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonObject jsonObject = hoverable.b();
|
||||||
|
JsonElement json = hoverable.b().get("contents");
|
||||||
|
if (json.getAsJsonObject().get("id") == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (json.getAsJsonObject().get("tag") == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String id = json.getAsJsonObject().get("id").toString();
|
||||||
|
String tag = json.getAsJsonObject().get("tag").toString();
|
||||||
|
ItemStack itemStack = getFromTag(tag, id);
|
||||||
|
|
||||||
|
Display.displayAndFinalize(itemStack);
|
||||||
|
|
||||||
|
json.getAsJsonObject().remove("tag");
|
||||||
|
String newTag = toJson(itemStack);
|
||||||
|
json.getAsJsonObject().add("tag", new JsonPrimitive(newTag));
|
||||||
|
|
||||||
|
jsonObject.remove("contents");
|
||||||
|
jsonObject.add("contents", json);
|
||||||
|
ChatHoverable newHoverable = ChatHoverable.a(jsonObject);
|
||||||
|
ChatModifier modifier = component.getChatModifier();
|
||||||
|
modifier = modifier.setChatHoverable(newHoverable);
|
||||||
|
|
||||||
|
((ChatBaseComponent) component).setChatModifier(modifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ItemStack getFromTag(@NotNull final String jsonTag,
|
||||||
|
@NotNull final String id) {
|
||||||
|
String processedId = id;
|
||||||
|
String processedJsonTag = jsonTag;
|
||||||
|
processedId = processedId.replace("minecraft:", "");
|
||||||
|
processedId = processedId.toUpperCase();
|
||||||
|
processedId = processedId.replace("\"", "");
|
||||||
|
processedJsonTag = processedJsonTag.substring(1, processedJsonTag.length() - 1);
|
||||||
|
processedJsonTag = processedJsonTag.replace("id:", "\"id\":");
|
||||||
|
processedJsonTag = processedJsonTag.replace("\\", "");
|
||||||
|
Material material = Material.getMaterial(processedId);
|
||||||
|
|
||||||
|
assert material != null;
|
||||||
|
ItemStack itemStack = new ItemStack(material);
|
||||||
|
net.minecraft.server.v1_16_R1.ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack);
|
||||||
|
|
||||||
|
try {
|
||||||
|
nmsStack.setTag(MojangsonParser.parse(processedJsonTag));
|
||||||
|
} catch (CommandSyntaxException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return CraftItemStack.asBukkitCopy(nmsStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String toJson(@NotNull final ItemStack itemStack) {
|
||||||
|
return CraftItemStack.asNMSCopy(itemStack).getOrCreateTag().toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package com.willfp.eco.proxy.v1_16_R1;
|
||||||
|
|
||||||
|
import com.willfp.eco.proxy.proxies.VillagerTradeProxy;
|
||||||
|
import com.willfp.eco.util.display.Display;
|
||||||
|
import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftItemStack;
|
||||||
|
import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftMerchantRecipe;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.MerchantRecipe;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
public final class VillagerTrade implements VillagerTradeProxy {
|
||||||
|
@Override
|
||||||
|
public void displayTrade(@NotNull final MerchantRecipe merchantRecipe) {
|
||||||
|
try {
|
||||||
|
// Bukkit MerchantRecipe result
|
||||||
|
Field fResult = MerchantRecipe.class.getDeclaredField("result");
|
||||||
|
fResult.setAccessible(true);
|
||||||
|
ItemStack result = merchantRecipe.getResult();
|
||||||
|
Display.display(result);
|
||||||
|
fResult.set(merchantRecipe, result);
|
||||||
|
|
||||||
|
// Get NMS MerchantRecipe from CraftMerchantRecipe
|
||||||
|
Field fHandle = CraftMerchantRecipe.class.getDeclaredField("handle");
|
||||||
|
fHandle.setAccessible(true);
|
||||||
|
net.minecraft.server.v1_16_R1.MerchantRecipe handle = (net.minecraft.server.v1_16_R1.MerchantRecipe) fHandle.get(merchantRecipe); // NMS Recipe
|
||||||
|
|
||||||
|
Field fSelling = net.minecraft.server.v1_16_R1.MerchantRecipe.class.getDeclaredField("sellingItem");
|
||||||
|
fSelling.setAccessible(true);
|
||||||
|
|
||||||
|
ItemStack selling = CraftItemStack.asBukkitCopy(handle.sellingItem);
|
||||||
|
Display.display(selling);
|
||||||
|
|
||||||
|
fSelling.set(handle, CraftItemStack.asNMSCopy(selling));
|
||||||
|
} catch (IllegalAccessException | NoSuchFieldException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
6
eco-core/core-nms/v1_16_R2/build.gradle
Normal file
6
eco-core/core-nms/v1_16_R2/build.gradle
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
group 'com.willfp'
|
||||||
|
version rootProject.version
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compileOnly 'org.spigotmc:spigot:1.16.3-R0.1-SNAPSHOT'
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.willfp.eco.proxy.v1_16_R2;
|
||||||
|
|
||||||
|
import com.willfp.eco.proxy.proxies.AutoCraftProxy;
|
||||||
|
import net.minecraft.server.v1_16_R2.MinecraftKey;
|
||||||
|
import net.minecraft.server.v1_16_R2.PacketPlayOutAutoRecipe;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
public final class AutoCraft implements AutoCraftProxy {
|
||||||
|
@Override
|
||||||
|
public void modifyPacket(@NotNull final Object packet) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
PacketPlayOutAutoRecipe recipePacket = (PacketPlayOutAutoRecipe) packet;
|
||||||
|
Field fKey = recipePacket.getClass().getDeclaredField("b");
|
||||||
|
fKey.setAccessible(true);
|
||||||
|
MinecraftKey key = (MinecraftKey) fKey.get(recipePacket);
|
||||||
|
fKey.set(recipePacket, new MinecraftKey(key.getNamespace(), key.getKey() + "_displayed"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
package com.willfp.eco.proxy.v1_16_R2;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonPrimitive;
|
||||||
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
|
import com.willfp.eco.proxy.proxies.ChatComponentProxy;
|
||||||
|
import com.willfp.eco.util.display.Display;
|
||||||
|
import net.minecraft.server.v1_16_R2.ChatBaseComponent;
|
||||||
|
import net.minecraft.server.v1_16_R2.ChatHoverable;
|
||||||
|
import net.minecraft.server.v1_16_R2.ChatMessage;
|
||||||
|
import net.minecraft.server.v1_16_R2.ChatModifier;
|
||||||
|
import net.minecraft.server.v1_16_R2.IChatBaseComponent;
|
||||||
|
import net.minecraft.server.v1_16_R2.MojangsonParser;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.craftbukkit.v1_16_R2.inventory.CraftItemStack;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public final class ChatComponent implements ChatComponentProxy {
|
||||||
|
@Override
|
||||||
|
public Object modifyComponent(@NotNull final Object object) {
|
||||||
|
if (!(object instanceof IChatBaseComponent)) {
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
IChatBaseComponent chatComponent = (IChatBaseComponent) object;
|
||||||
|
chatComponent.stream().forEach(this::modifyBaseComponent);
|
||||||
|
|
||||||
|
return chatComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void modifyBaseComponent(@NotNull final IChatBaseComponent component) {
|
||||||
|
component.getSiblings().forEach(this::modifyBaseComponent);
|
||||||
|
if (component instanceof ChatMessage) {
|
||||||
|
Arrays.stream(((ChatMessage) component).getArgs())
|
||||||
|
.filter(o -> o instanceof IChatBaseComponent)
|
||||||
|
.map(o -> (IChatBaseComponent) o)
|
||||||
|
.forEach(this::modifyBaseComponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatHoverable hoverable = component.getChatModifier().getHoverEvent();
|
||||||
|
|
||||||
|
if (hoverable == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonObject jsonObject = hoverable.b();
|
||||||
|
JsonElement json = hoverable.b().get("contents");
|
||||||
|
if (json.getAsJsonObject().get("id") == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (json.getAsJsonObject().get("tag") == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String id = json.getAsJsonObject().get("id").toString();
|
||||||
|
String tag = json.getAsJsonObject().get("tag").toString();
|
||||||
|
ItemStack itemStack = getFromTag(tag, id);
|
||||||
|
|
||||||
|
Display.displayAndFinalize(itemStack);
|
||||||
|
|
||||||
|
json.getAsJsonObject().remove("tag");
|
||||||
|
String newTag = toJson(itemStack);
|
||||||
|
json.getAsJsonObject().add("tag", new JsonPrimitive(newTag));
|
||||||
|
|
||||||
|
jsonObject.remove("contents");
|
||||||
|
jsonObject.add("contents", json);
|
||||||
|
ChatHoverable newHoverable = ChatHoverable.a(jsonObject);
|
||||||
|
ChatModifier modifier = component.getChatModifier();
|
||||||
|
modifier = modifier.setChatHoverable(newHoverable);
|
||||||
|
|
||||||
|
((ChatBaseComponent) component).setChatModifier(modifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ItemStack getFromTag(@NotNull final String jsonTag,
|
||||||
|
@NotNull final String id) {
|
||||||
|
String processedId = id;
|
||||||
|
String processedJsonTag = jsonTag;
|
||||||
|
processedId = processedId.replace("minecraft:", "");
|
||||||
|
processedId = processedId.toUpperCase();
|
||||||
|
processedId = processedId.replace("\"", "");
|
||||||
|
processedJsonTag = processedJsonTag.substring(1, processedJsonTag.length() - 1);
|
||||||
|
processedJsonTag = processedJsonTag.replace("id:", "\"id\":");
|
||||||
|
processedJsonTag = processedJsonTag.replace("\\", "");
|
||||||
|
Material material = Material.getMaterial(processedId);
|
||||||
|
|
||||||
|
assert material != null;
|
||||||
|
ItemStack itemStack = new ItemStack(material);
|
||||||
|
net.minecraft.server.v1_16_R2.ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack);
|
||||||
|
|
||||||
|
try {
|
||||||
|
nmsStack.setTag(MojangsonParser.parse(processedJsonTag));
|
||||||
|
} catch (CommandSyntaxException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return CraftItemStack.asBukkitCopy(nmsStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String toJson(@NotNull final ItemStack itemStack) {
|
||||||
|
return CraftItemStack.asNMSCopy(itemStack).getOrCreateTag().toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package com.willfp.eco.proxy.v1_16_R2;
|
||||||
|
|
||||||
|
import com.willfp.eco.proxy.proxies.VillagerTradeProxy;
|
||||||
|
import com.willfp.eco.util.display.Display;
|
||||||
|
import org.bukkit.craftbukkit.v1_16_R2.inventory.CraftItemStack;
|
||||||
|
import org.bukkit.craftbukkit.v1_16_R2.inventory.CraftMerchantRecipe;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.MerchantRecipe;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
public final class VillagerTrade implements VillagerTradeProxy {
|
||||||
|
@Override
|
||||||
|
public void displayTrade(@NotNull final MerchantRecipe merchantRecipe) {
|
||||||
|
try {
|
||||||
|
// Bukkit MerchantRecipe result
|
||||||
|
Field fResult = MerchantRecipe.class.getDeclaredField("result");
|
||||||
|
fResult.setAccessible(true);
|
||||||
|
ItemStack result = merchantRecipe.getResult();
|
||||||
|
Display.display(result);
|
||||||
|
fResult.set(merchantRecipe, result);
|
||||||
|
|
||||||
|
// Get NMS MerchantRecipe from CraftMerchantRecipe
|
||||||
|
Field fHandle = CraftMerchantRecipe.class.getDeclaredField("handle");
|
||||||
|
fHandle.setAccessible(true);
|
||||||
|
net.minecraft.server.v1_16_R2.MerchantRecipe handle = (net.minecraft.server.v1_16_R2.MerchantRecipe) fHandle.get(merchantRecipe); // NMS Recipe
|
||||||
|
|
||||||
|
Field fSelling = net.minecraft.server.v1_16_R2.MerchantRecipe.class.getDeclaredField("sellingItem");
|
||||||
|
fSelling.setAccessible(true);
|
||||||
|
|
||||||
|
ItemStack selling = CraftItemStack.asBukkitCopy(handle.sellingItem);
|
||||||
|
Display.display(selling);
|
||||||
|
|
||||||
|
fSelling.set(handle, CraftItemStack.asNMSCopy(selling));
|
||||||
|
} catch (IllegalAccessException | NoSuchFieldException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
6
eco-core/core-nms/v1_16_R3/build.gradle
Normal file
6
eco-core/core-nms/v1_16_R3/build.gradle
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
group 'com.willfp'
|
||||||
|
version rootProject.version
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compileOnly 'org.spigotmc:spigot:1.16.4-R0.1-SNAPSHOT'
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.willfp.eco.proxy.v1_16_R3;
|
||||||
|
|
||||||
|
import com.willfp.eco.proxy.proxies.AutoCraftProxy;
|
||||||
|
import net.minecraft.server.v1_16_R3.MinecraftKey;
|
||||||
|
import net.minecraft.server.v1_16_R3.PacketPlayOutAutoRecipe;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
public final class AutoCraft implements AutoCraftProxy {
|
||||||
|
@Override
|
||||||
|
public void modifyPacket(@NotNull final Object packet) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
PacketPlayOutAutoRecipe recipePacket = (PacketPlayOutAutoRecipe) packet;
|
||||||
|
Field fKey = recipePacket.getClass().getDeclaredField("b");
|
||||||
|
fKey.setAccessible(true);
|
||||||
|
MinecraftKey key = (MinecraftKey) fKey.get(recipePacket);
|
||||||
|
fKey.set(recipePacket, new MinecraftKey(key.getNamespace(), key.getKey() + "_displayed"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
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.proxy.proxies.ChatComponentProxy;
|
||||||
|
import com.willfp.eco.util.display.Display;
|
||||||
|
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.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public final class ChatComponent implements ChatComponentProxy {
|
||||||
|
@Override
|
||||||
|
public Object modifyComponent(@NotNull final Object object) {
|
||||||
|
if (!(object instanceof IChatBaseComponent)) {
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
IChatBaseComponent chatComponent = (IChatBaseComponent) object;
|
||||||
|
chatComponent.stream().forEach(this::modifyBaseComponent);
|
||||||
|
|
||||||
|
return chatComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void modifyBaseComponent(@NotNull final IChatBaseComponent component) {
|
||||||
|
component.getSiblings().forEach(this::modifyBaseComponent);
|
||||||
|
if (component instanceof ChatMessage) {
|
||||||
|
Arrays.stream(((ChatMessage) component).getArgs())
|
||||||
|
.filter(o -> o instanceof IChatBaseComponent)
|
||||||
|
.map(o -> (IChatBaseComponent) o)
|
||||||
|
.forEach(this::modifyBaseComponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatHoverable hoverable = component.getChatModifier().getHoverEvent();
|
||||||
|
|
||||||
|
if (hoverable == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonObject jsonObject = hoverable.b();
|
||||||
|
JsonElement json = hoverable.b().get("contents");
|
||||||
|
if (json.getAsJsonObject().get("id") == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (json.getAsJsonObject().get("tag") == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String id = json.getAsJsonObject().get("id").toString();
|
||||||
|
String tag = json.getAsJsonObject().get("tag").toString();
|
||||||
|
ItemStack itemStack = getFromTag(tag, id);
|
||||||
|
|
||||||
|
Display.displayAndFinalize(itemStack);
|
||||||
|
|
||||||
|
json.getAsJsonObject().remove("tag");
|
||||||
|
String newTag = toJson(itemStack);
|
||||||
|
json.getAsJsonObject().add("tag", new JsonPrimitive(newTag));
|
||||||
|
|
||||||
|
jsonObject.remove("contents");
|
||||||
|
jsonObject.add("contents", json);
|
||||||
|
ChatHoverable newHoverable = ChatHoverable.a(jsonObject);
|
||||||
|
ChatModifier modifier = component.getChatModifier();
|
||||||
|
modifier = modifier.setChatHoverable(newHoverable);
|
||||||
|
|
||||||
|
((ChatBaseComponent) component).setChatModifier(modifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ItemStack getFromTag(@NotNull final String jsonTag,
|
||||||
|
@NotNull final String id) {
|
||||||
|
String processedId = id;
|
||||||
|
String processedJsonTag = jsonTag;
|
||||||
|
processedId = processedId.replace("minecraft:", "");
|
||||||
|
processedId = processedId.toUpperCase();
|
||||||
|
processedId = processedId.replace("\"", "");
|
||||||
|
processedJsonTag = processedJsonTag.substring(1, processedJsonTag.length() - 1);
|
||||||
|
processedJsonTag = processedJsonTag.replace("id:", "\"id\":");
|
||||||
|
processedJsonTag = processedJsonTag.replace("\\", "");
|
||||||
|
Material material = Material.getMaterial(processedId);
|
||||||
|
|
||||||
|
assert material != null;
|
||||||
|
ItemStack itemStack = new ItemStack(material);
|
||||||
|
net.minecraft.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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package com.willfp.eco.proxy.v1_16_R3;
|
||||||
|
|
||||||
|
import com.willfp.eco.proxy.proxies.VillagerTradeProxy;
|
||||||
|
import com.willfp.eco.util.display.Display;
|
||||||
|
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack;
|
||||||
|
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftMerchantRecipe;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.MerchantRecipe;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
public final class VillagerTrade implements VillagerTradeProxy {
|
||||||
|
@Override
|
||||||
|
public void displayTrade(@NotNull final MerchantRecipe merchantRecipe) {
|
||||||
|
try {
|
||||||
|
// Bukkit MerchantRecipe result
|
||||||
|
Field fResult = MerchantRecipe.class.getDeclaredField("result");
|
||||||
|
fResult.setAccessible(true);
|
||||||
|
ItemStack result = merchantRecipe.getResult();
|
||||||
|
Display.display(result);
|
||||||
|
fResult.set(merchantRecipe, result);
|
||||||
|
|
||||||
|
// Get NMS MerchantRecipe from CraftMerchantRecipe
|
||||||
|
Field fHandle = CraftMerchantRecipe.class.getDeclaredField("handle");
|
||||||
|
fHandle.setAccessible(true);
|
||||||
|
net.minecraft.server.v1_16_R3.MerchantRecipe handle = (net.minecraft.server.v1_16_R3.MerchantRecipe) fHandle.get(merchantRecipe); // NMS RecipeR
|
||||||
|
|
||||||
|
Field fSelling = net.minecraft.server.v1_16_R3.MerchantRecipe.class.getDeclaredField("sellingItem");
|
||||||
|
fSelling.setAccessible(true);
|
||||||
|
|
||||||
|
ItemStack selling = CraftItemStack.asBukkitCopy(handle.sellingItem);
|
||||||
|
Display.display(selling);
|
||||||
|
|
||||||
|
fSelling.set(handle, CraftItemStack.asNMSCopy(selling));
|
||||||
|
} catch (IllegalAccessException | NoSuchFieldException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
25
eco-core/core-plugin/build.gradle
Normal file
25
eco-core/core-plugin/build.gradle
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
group 'com.willfp'
|
||||||
|
version rootProject.version
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation 'org.apache.maven:maven-artifact:3.0.3'
|
||||||
|
implementation 'org.bstats:bstats-bukkit:1.7'
|
||||||
|
compileOnly project(":eco-core:core-proxy")
|
||||||
|
compileOnly 'com.comphenix.protocol:ProtocolLib:4.6.0-SNAPSHOT'
|
||||||
|
compileOnly 'com.sk89q.worldguard:worldguard-bukkit:7.0.4-SNAPSHOT'
|
||||||
|
compileOnly 'com.github.TechFortress:GriefPrevention:16.14.0'
|
||||||
|
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.96.2.0'
|
||||||
|
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 fileTree(dir: '../../lib', include: ['*.jar'])
|
||||||
|
}
|
||||||
|
|
||||||
|
processResources {
|
||||||
|
filesNotMatching(["**/*.png", "**/models/**", "**/textures/**"]) {
|
||||||
|
expand projectVersion: project.version
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
package com.willfp.eco.spigot;
|
||||||
|
|
||||||
|
import com.willfp.eco.spigot.display.packets.PacketAutoRecipe;
|
||||||
|
import com.willfp.eco.spigot.display.packets.PacketChat;
|
||||||
|
import com.willfp.eco.spigot.display.packets.PacketOpenWindowMerchant;
|
||||||
|
import com.willfp.eco.spigot.display.packets.PacketSetCreativeSlot;
|
||||||
|
import com.willfp.eco.spigot.display.packets.PacketSetSlot;
|
||||||
|
import com.willfp.eco.spigot.display.packets.PacketWindowItems;
|
||||||
|
import com.willfp.eco.spigot.integrations.anticheat.AnticheatAAC;
|
||||||
|
import com.willfp.eco.spigot.integrations.anticheat.AnticheatMatrix;
|
||||||
|
import com.willfp.eco.spigot.integrations.anticheat.AnticheatNCP;
|
||||||
|
import com.willfp.eco.spigot.integrations.antigrief.AntigriefFactionsUUID;
|
||||||
|
import com.willfp.eco.spigot.integrations.antigrief.AntigriefGriefPrevention;
|
||||||
|
import com.willfp.eco.spigot.integrations.antigrief.AntigriefKingdoms;
|
||||||
|
import com.willfp.eco.spigot.integrations.antigrief.AntigriefLands;
|
||||||
|
import com.willfp.eco.spigot.integrations.antigrief.AntigriefTowny;
|
||||||
|
import com.willfp.eco.spigot.integrations.antigrief.AntigriefWorldGuard;
|
||||||
|
import com.willfp.eco.spigot.integrations.mcmmo.McmmoIntegrationImpl;
|
||||||
|
import com.willfp.eco.util.command.AbstractCommand;
|
||||||
|
import com.willfp.eco.util.display.Display;
|
||||||
|
import com.willfp.eco.util.drops.internal.FastCollatedDropQueue;
|
||||||
|
import com.willfp.eco.util.events.armorequip.ArmorListener;
|
||||||
|
import com.willfp.eco.util.events.armorequip.DispenserArmorListener;
|
||||||
|
import com.willfp.eco.util.events.entitydeathbyentity.EntityDeathByEntityListeners;
|
||||||
|
import com.willfp.eco.util.events.naturalexpgainevent.NaturalExpGainListeners;
|
||||||
|
import com.willfp.eco.util.integrations.IntegrationLoader;
|
||||||
|
import com.willfp.eco.util.integrations.anticheat.AnticheatManager;
|
||||||
|
import com.willfp.eco.util.integrations.antigrief.AntigriefManager;
|
||||||
|
import com.willfp.eco.util.integrations.mcmmo.McmmoManager;
|
||||||
|
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
|
||||||
|
import com.willfp.eco.util.protocollib.AbstractPacketAdapter;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class EcoPlugin extends AbstractEcoPlugin {
|
||||||
|
/**
|
||||||
|
* Instance of eco.
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
private static EcoPlugin instance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance of eco.
|
||||||
|
*/
|
||||||
|
public EcoPlugin() {
|
||||||
|
super("eco", 87955, 10043, "com.willfp.eco.proxy", "&a");
|
||||||
|
instance = this;
|
||||||
|
Display.setFinalizeKey(this.getNamespacedKeyFactory().create("finalized"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enable() {
|
||||||
|
new FastCollatedDropQueue.CollatedRunnable(this);
|
||||||
|
this.getEventManager().registerListener(new NaturalExpGainListeners());
|
||||||
|
this.getEventManager().registerListener(new ArmorListener());
|
||||||
|
this.getEventManager().registerListener(new DispenserArmorListener());
|
||||||
|
this.getEventManager().registerListener(new EntityDeathByEntityListeners(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disable() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void load() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReload() {
|
||||||
|
new FastCollatedDropQueue.CollatedRunnable(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postLoad() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<IntegrationLoader> getIntegrationLoaders() {
|
||||||
|
return Arrays.asList(
|
||||||
|
// AntiGrief
|
||||||
|
new IntegrationLoader("WorldGuard", () -> AntigriefManager.register(new AntigriefWorldGuard())),
|
||||||
|
new IntegrationLoader("GriefPrevention", () -> AntigriefManager.register(new AntigriefGriefPrevention())),
|
||||||
|
new IntegrationLoader("FactionsUUID", () -> AntigriefManager.register(new AntigriefFactionsUUID())),
|
||||||
|
new IntegrationLoader("Towny", () -> AntigriefManager.register(new AntigriefTowny())),
|
||||||
|
new IntegrationLoader("Lands", () -> AntigriefManager.register(new AntigriefLands(this))),
|
||||||
|
new IntegrationLoader("Kingdoms", () -> AntigriefManager.register(new AntigriefKingdoms())),
|
||||||
|
|
||||||
|
// Anticheat
|
||||||
|
new IntegrationLoader("AAC5", () -> AnticheatManager.register(this, new AnticheatAAC())),
|
||||||
|
new IntegrationLoader("Matrix", () -> AnticheatManager.register(this, new AnticheatMatrix())),
|
||||||
|
new IntegrationLoader("NoCheatPlus", () -> AnticheatManager.register(this, new AnticheatNCP())),
|
||||||
|
|
||||||
|
// Misc
|
||||||
|
new IntegrationLoader("mcMMO", () -> McmmoManager.register(new McmmoIntegrationImpl()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<AbstractCommand> getCommands() {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<AbstractPacketAdapter> getPacketAdapters() {
|
||||||
|
return Arrays.asList(
|
||||||
|
new PacketAutoRecipe(this),
|
||||||
|
new PacketChat(this),
|
||||||
|
new PacketOpenWindowMerchant(this),
|
||||||
|
new PacketSetCreativeSlot(this),
|
||||||
|
new PacketSetSlot(this),
|
||||||
|
new PacketWindowItems(this)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Listener> getListeners() {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Class<?>> getUpdatableClasses() {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,13 +1,12 @@
|
|||||||
package com.willfp.eco.util;
|
package com.willfp.eco.spigot;
|
||||||
|
|
||||||
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
|
|
||||||
import com.willfp.eco.util.proxy.AbstractProxy;
|
import com.willfp.eco.util.proxy.AbstractProxy;
|
||||||
import com.willfp.eco.util.proxy.ProxyFactory;
|
import com.willfp.eco.proxy.util.ProxyFactory;
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
@UtilityClass
|
@UtilityClass
|
||||||
public class ProxyUtils {
|
public class InternalProxyUtils {
|
||||||
/**
|
/**
|
||||||
* Get the implementation of a specified proxy.
|
* Get the implementation of a specified proxy.
|
||||||
*
|
*
|
||||||
@@ -16,6 +15,6 @@ public class ProxyUtils {
|
|||||||
* @return The proxy implementation.
|
* @return The proxy implementation.
|
||||||
*/
|
*/
|
||||||
public @NotNull <T extends AbstractProxy> T getProxy(@NotNull final Class<T> proxyClass) {
|
public @NotNull <T extends AbstractProxy> T getProxy(@NotNull final Class<T> proxyClass) {
|
||||||
return new ProxyFactory<>(AbstractEcoPlugin.getInstance(), proxyClass).getProxy();
|
return new ProxyFactory<>(EcoPlugin.getInstance(), proxyClass).getProxy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package com.willfp.eco.spigot.display.packets;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.PacketType;
|
||||||
|
import com.comphenix.protocol.ProtocolLibrary;
|
||||||
|
import com.comphenix.protocol.events.PacketContainer;
|
||||||
|
import com.willfp.eco.proxy.proxies.AutoCraftProxy;
|
||||||
|
import com.willfp.eco.spigot.InternalProxyUtils;
|
||||||
|
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
|
||||||
|
import com.willfp.eco.util.protocollib.AbstractPacketAdapter;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
|
||||||
|
public class PacketAutoRecipe extends AbstractPacketAdapter {
|
||||||
|
/**
|
||||||
|
* Instantiate a new listener for {@link PacketType.Play.Server#SET_SLOT}.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin to listen through.
|
||||||
|
*/
|
||||||
|
public PacketAutoRecipe(@NotNull final AbstractEcoPlugin plugin) {
|
||||||
|
super(plugin, PacketType.Play.Server.AUTO_RECIPE, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSend(@NotNull final PacketContainer packet,
|
||||||
|
@NotNull final Player player) {
|
||||||
|
if (!AbstractEcoPlugin.LOADED_ECO_PLUGINS.contains(packet.getMinecraftKeys().getValues().get(0).getFullKey().split(":")[0])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (packet.getMinecraftKeys().getValues().get(0).getFullKey().split(":")[1].contains("displayed")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
InternalProxyUtils.getProxy(AutoCraftProxy.class).modifyPacket(packet.getHandle());
|
||||||
|
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketContainer newAutoRecipe = new PacketContainer(PacketType.Play.Server.AUTO_RECIPE);
|
||||||
|
newAutoRecipe.getMinecraftKeys().write(0, packet.getMinecraftKeys().read(0));
|
||||||
|
|
||||||
|
try {
|
||||||
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, newAutoRecipe);
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.willfp.eco.spigot.display.packets;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.PacketType;
|
||||||
|
import com.comphenix.protocol.events.ListenerPriority;
|
||||||
|
import com.comphenix.protocol.events.PacketContainer;
|
||||||
|
import com.comphenix.protocol.wrappers.WrappedChatComponent;
|
||||||
|
import com.willfp.eco.proxy.proxies.ChatComponentProxy;
|
||||||
|
import com.willfp.eco.spigot.InternalProxyUtils;
|
||||||
|
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
|
||||||
|
import com.willfp.eco.util.protocollib.AbstractPacketAdapter;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class PacketChat extends AbstractPacketAdapter {
|
||||||
|
/**
|
||||||
|
* Instantiate a new listener for {@link PacketType.Play.Server#CHAT}.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin to listen through.
|
||||||
|
*/
|
||||||
|
public PacketChat(@NotNull final AbstractEcoPlugin plugin) {
|
||||||
|
super(plugin, PacketType.Play.Server.CHAT, ListenerPriority.MONITOR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSend(@NotNull final PacketContainer packet,
|
||||||
|
@NotNull final Player player) {
|
||||||
|
for (int i = 0; i < packet.getChatComponents().size(); i++) {
|
||||||
|
WrappedChatComponent component = packet.getChatComponents().read(i);
|
||||||
|
if (component == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (component.getHandle() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WrappedChatComponent newComponent = WrappedChatComponent.fromHandle(InternalProxyUtils.getProxy(ChatComponentProxy.class).modifyComponent(component.getHandle()));
|
||||||
|
packet.getChatComponents().write(i, newComponent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.willfp.eco.spigot.display.packets;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.PacketType;
|
||||||
|
import com.comphenix.protocol.events.PacketContainer;
|
||||||
|
import com.willfp.eco.proxy.proxies.VillagerTradeProxy;
|
||||||
|
import com.willfp.eco.spigot.InternalProxyUtils;
|
||||||
|
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
|
||||||
|
import com.willfp.eco.util.protocollib.AbstractPacketAdapter;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.MerchantRecipe;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class PacketOpenWindowMerchant extends AbstractPacketAdapter {
|
||||||
|
/**
|
||||||
|
* Instantiate a new listener for {@link PacketType.Play.Server#OPEN_WINDOW_MERCHANT}.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin to listen through.
|
||||||
|
*/
|
||||||
|
public PacketOpenWindowMerchant(@NotNull final AbstractEcoPlugin plugin) {
|
||||||
|
super(plugin, PacketType.Play.Server.OPEN_WINDOW_MERCHANT, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSend(@NotNull final PacketContainer packet,
|
||||||
|
@NotNull final Player player) {
|
||||||
|
List<MerchantRecipe> recipes = packet.getMerchantRecipeLists().readSafely(0);
|
||||||
|
|
||||||
|
recipes = recipes.stream().peek(merchantRecipe -> InternalProxyUtils.getProxy(VillagerTradeProxy.class).displayTrade(merchantRecipe)).collect(Collectors.toList());
|
||||||
|
|
||||||
|
packet.getMerchantRecipeLists().writeSafely(0, recipes);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.willfp.eco.spigot.display.packets;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.PacketType;
|
||||||
|
import com.comphenix.protocol.events.PacketContainer;
|
||||||
|
import com.willfp.eco.util.display.Display;
|
||||||
|
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
|
||||||
|
import com.willfp.eco.util.protocollib.AbstractPacketAdapter;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class PacketSetCreativeSlot extends AbstractPacketAdapter {
|
||||||
|
/**
|
||||||
|
* Instantiate a new listener for {@link PacketType.Play.Client#SET_CREATIVE_SLOT}.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin to listen through.
|
||||||
|
*/
|
||||||
|
public PacketSetCreativeSlot(@NotNull final AbstractEcoPlugin plugin) {
|
||||||
|
super(plugin, PacketType.Play.Client.SET_CREATIVE_SLOT, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceive(@NotNull final PacketContainer packet,
|
||||||
|
@NotNull final Player player) {
|
||||||
|
packet.getItemModifier().modify(0, Display::revert);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.willfp.eco.spigot.display.packets;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.PacketType;
|
||||||
|
import com.comphenix.protocol.events.PacketContainer;
|
||||||
|
import com.willfp.eco.util.display.Display;
|
||||||
|
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
|
||||||
|
import com.willfp.eco.util.protocollib.AbstractPacketAdapter;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class PacketSetSlot extends AbstractPacketAdapter {
|
||||||
|
/**
|
||||||
|
* Instantiate a new listener for {@link PacketType.Play.Server#SET_SLOT}.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin to listen through.
|
||||||
|
*/
|
||||||
|
public PacketSetSlot(@NotNull final AbstractEcoPlugin plugin) {
|
||||||
|
super(plugin, PacketType.Play.Server.SET_SLOT, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSend(@NotNull final PacketContainer packet,
|
||||||
|
@NotNull final Player player) {
|
||||||
|
packet.getItemModifier().modify(0, Display::display);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package com.willfp.eco.spigot.display.packets;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.PacketType;
|
||||||
|
import com.comphenix.protocol.events.PacketContainer;
|
||||||
|
import com.willfp.eco.util.display.Display;
|
||||||
|
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
|
||||||
|
import com.willfp.eco.util.protocollib.AbstractPacketAdapter;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class PacketWindowItems extends AbstractPacketAdapter {
|
||||||
|
/**
|
||||||
|
* Instantiate a new listener for {@link PacketType.Play.Server#WINDOW_ITEMS}.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin to listen through.
|
||||||
|
*/
|
||||||
|
public PacketWindowItems(@NotNull final AbstractEcoPlugin plugin) {
|
||||||
|
super(plugin, PacketType.Play.Server.WINDOW_ITEMS, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSend(@NotNull final PacketContainer packet,
|
||||||
|
@NotNull final Player player) {
|
||||||
|
packet.getItemListModifier().modify(0, itemStacks -> {
|
||||||
|
if (itemStacks == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
itemStacks.forEach(Display::display);
|
||||||
|
return itemStacks;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.willfp.eco.util.integrations.anticheat.plugins;
|
package com.willfp.eco.spigot.integrations.anticheat;
|
||||||
|
|
||||||
import com.willfp.eco.util.integrations.anticheat.AnticheatWrapper;
|
import com.willfp.eco.util.integrations.anticheat.AnticheatWrapper;
|
||||||
import me.konsolas.aac.api.AACAPI;
|
import me.konsolas.aac.api.AACAPI;
|
||||||
@@ -12,9 +12,9 @@ import java.util.Objects;
|
|||||||
|
|
||||||
public class AnticheatAAC implements AnticheatWrapper, Listener {
|
public class AnticheatAAC implements AnticheatWrapper, Listener {
|
||||||
/**
|
/**
|
||||||
* AAC exemption for EcoEnchants.
|
* AAC exemption for eco.
|
||||||
*/
|
*/
|
||||||
private final AACExemption ecoEnchantsExemption = new AACExemption("EcoEnchants");
|
private final AACExemption ecoExemption = new AACExemption("eco");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AAC api.
|
* AAC api.
|
||||||
@@ -28,11 +28,11 @@ public class AnticheatAAC implements AnticheatWrapper, Listener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exempt(@NotNull final Player player) {
|
public void exempt(@NotNull final Player player) {
|
||||||
api.addExemption(player, ecoEnchantsExemption);
|
api.addExemption(player, ecoExemption);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unexempt(@NotNull final Player player) {
|
public void unexempt(@NotNull final Player player) {
|
||||||
api.removeExemption(player, ecoEnchantsExemption);
|
api.removeExemption(player, ecoExemption);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.willfp.eco.util.integrations.anticheat.plugins;
|
package com.willfp.eco.spigot.integrations.anticheat;
|
||||||
|
|
||||||
import com.willfp.eco.util.integrations.anticheat.AnticheatWrapper;
|
import com.willfp.eco.util.integrations.anticheat.AnticheatWrapper;
|
||||||
import me.rerere.matrix.api.events.PlayerViolationEvent;
|
import me.rerere.matrix.api.events.PlayerViolationEvent;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.willfp.eco.util.integrations.anticheat.plugins;
|
package com.willfp.eco.spigot.integrations.anticheat;
|
||||||
|
|
||||||
import com.willfp.eco.util.integrations.anticheat.AnticheatWrapper;
|
import com.willfp.eco.util.integrations.anticheat.AnticheatWrapper;
|
||||||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.willfp.eco.util.integrations.anticheat.plugins;
|
package com.willfp.eco.spigot.integrations.anticheat;
|
||||||
|
|
||||||
import com.willfp.eco.util.integrations.anticheat.AnticheatWrapper;
|
import com.willfp.eco.util.integrations.anticheat.AnticheatWrapper;
|
||||||
import me.vagdedes.spartan.api.PlayerViolationEvent;
|
import me.vagdedes.spartan.api.PlayerViolationEvent;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.willfp.eco.util.integrations.antigrief.plugins;
|
package com.willfp.eco.spigot.integrations.antigrief;
|
||||||
|
|
||||||
import com.massivecraft.factions.Board;
|
import com.massivecraft.factions.Board;
|
||||||
import com.massivecraft.factions.FLocation;
|
import com.massivecraft.factions.FLocation;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.willfp.eco.util.integrations.antigrief.plugins;
|
package com.willfp.eco.spigot.integrations.antigrief;
|
||||||
|
|
||||||
import com.willfp.eco.util.integrations.antigrief.AntigriefWrapper;
|
import com.willfp.eco.util.integrations.antigrief.AntigriefWrapper;
|
||||||
import me.ryanhamshire.GriefPrevention.Claim;
|
import me.ryanhamshire.GriefPrevention.Claim;
|
||||||
@@ -1,26 +1,43 @@
|
|||||||
package com.willfp.eco.util.integrations.antigrief.plugins;
|
package com.willfp.eco.spigot.integrations.antigrief;
|
||||||
|
|
||||||
import com.willfp.eco.util.integrations.antigrief.AntigriefWrapper;
|
import com.willfp.eco.util.integrations.antigrief.AntigriefWrapper;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.entity.LivingEntity;
|
import org.bukkit.entity.LivingEntity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.block.BlockBreakEvent;
|
|
||||||
import org.bukkit.event.block.BlockPlaceEvent;
|
|
||||||
import org.bukkit.inventory.EquipmentSlot;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.kingdoms.constants.kingdom.Kingdom;
|
import org.kingdoms.constants.kingdom.Kingdom;
|
||||||
|
import org.kingdoms.constants.kingdom.model.KingdomRelation;
|
||||||
import org.kingdoms.constants.land.Land;
|
import org.kingdoms.constants.land.Land;
|
||||||
|
import org.kingdoms.constants.player.DefaultKingdomPermission;
|
||||||
|
import org.kingdoms.constants.player.KingdomPlayer;
|
||||||
import org.kingdoms.managers.PvPManager;
|
import org.kingdoms.managers.PvPManager;
|
||||||
import org.kingdoms.managers.land.LandManager;
|
|
||||||
|
|
||||||
public class AntigriefKingdoms implements AntigriefWrapper {
|
public class AntigriefKingdoms implements AntigriefWrapper {
|
||||||
@Override
|
@Override
|
||||||
public boolean canBreakBlock(@NotNull final Player player,
|
public boolean canBreakBlock(@NotNull final Player player,
|
||||||
@NotNull final Block block) {
|
@NotNull final Block block) {
|
||||||
BlockBreakEvent event = new BlockBreakEvent(block, player);
|
KingdomPlayer kp = KingdomPlayer.getKingdomPlayer(player);
|
||||||
LandManager.onBreak(event);
|
if (kp.isAdmin()) {
|
||||||
return !event.isCancelled();
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Kingdom kingdom = kp.getKingdom();
|
||||||
|
if (kingdom == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Land land = Land.getLand(block);
|
||||||
|
|
||||||
|
if (land == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DefaultKingdomPermission permission = land.isNexusLand() ? DefaultKingdomPermission.NEXUS_BUILD : DefaultKingdomPermission.BUILD;
|
||||||
|
if (!kp.hasPermission(permission)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return kingdom.hasAttribute(land.getKingdom(), KingdomRelation.Attribute.BUILD);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -41,10 +58,7 @@ public class AntigriefKingdoms implements AntigriefWrapper {
|
|||||||
@Override
|
@Override
|
||||||
public boolean canPlaceBlock(@NotNull final Player player,
|
public boolean canPlaceBlock(@NotNull final Player player,
|
||||||
@NotNull final Block block) {
|
@NotNull final Block block) {
|
||||||
Block placedOn = block.getRelative(0, -1, 0);
|
return canBreakBlock(player, block);
|
||||||
BlockPlaceEvent event = new BlockPlaceEvent(block, block.getState(), placedOn, player.getInventory().getItemInMainHand(), player, true, EquipmentSlot.HAND);
|
|
||||||
LandManager.onPlace(event);
|
|
||||||
return !event.isCancelled();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.willfp.eco.util.integrations.antigrief.plugins;
|
package com.willfp.eco.spigot.integrations.antigrief;
|
||||||
|
|
||||||
import com.willfp.eco.util.internal.PluginDependent;
|
|
||||||
import com.willfp.eco.util.integrations.antigrief.AntigriefWrapper;
|
import com.willfp.eco.util.integrations.antigrief.AntigriefWrapper;
|
||||||
|
import com.willfp.eco.util.internal.PluginDependent;
|
||||||
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
|
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
|
||||||
import me.angeschossen.lands.api.integration.LandsIntegration;
|
import me.angeschossen.lands.api.integration.LandsIntegration;
|
||||||
import me.angeschossen.lands.api.land.Area;
|
import me.angeschossen.lands.api.land.Area;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.willfp.eco.util.integrations.antigrief.plugins;
|
package com.willfp.eco.spigot.integrations.antigrief;
|
||||||
|
|
||||||
import com.palmergames.bukkit.towny.object.Town;
|
import com.palmergames.bukkit.towny.object.Town;
|
||||||
import com.palmergames.bukkit.towny.object.TownyPermission;
|
import com.palmergames.bukkit.towny.object.TownyPermission;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.willfp.eco.util.integrations.antigrief.plugins;
|
package com.willfp.eco.spigot.integrations.antigrief;
|
||||||
|
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
import com.sk89q.worldguard.LocalPlayer;
|
import com.sk89q.worldguard.LocalPlayer;
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.willfp.eco.spigot.integrations.mcmmo;
|
||||||
|
|
||||||
|
import com.gmail.nossr50.datatypes.meta.BonusDropMeta;
|
||||||
|
import com.gmail.nossr50.events.fake.FakeEvent;
|
||||||
|
import com.gmail.nossr50.mcMMO;
|
||||||
|
import com.willfp.eco.util.integrations.mcmmo.McmmoWrapper;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class McmmoIntegrationImpl implements McmmoWrapper {
|
||||||
|
@Override
|
||||||
|
public int getBonusDropCount(@NotNull final Block block) {
|
||||||
|
if (block.getMetadata(mcMMO.BONUS_DROPS_METAKEY).size() > 0) {
|
||||||
|
BonusDropMeta bonusDropMeta = (BonusDropMeta) block.getMetadata(mcMMO.BONUS_DROPS_METAKEY).get(0);
|
||||||
|
return bonusDropMeta.asInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFake(@NotNull final Event event) {
|
||||||
|
return event instanceof FakeEvent;
|
||||||
|
}
|
||||||
|
}
|
||||||
0
eco-core/core-plugin/src/main/resources/config.yml
Normal file
0
eco-core/core-plugin/src/main/resources/config.yml
Normal file
0
eco-core/core-plugin/src/main/resources/lang.yml
Normal file
0
eco-core/core-plugin/src/main/resources/lang.yml
Normal file
27
eco-core/core-plugin/src/main/resources/plugin.yml
Normal file
27
eco-core/core-plugin/src/main/resources/plugin.yml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
name: eco
|
||||||
|
version: ${projectVersion}
|
||||||
|
main: com.willfp.eco.spigot.EcoPlugin
|
||||||
|
api-version: 1.15
|
||||||
|
authors: [Auxilor]
|
||||||
|
website: willfp.com
|
||||||
|
loadbefore:
|
||||||
|
- EcoEnchants
|
||||||
|
- Talismans
|
||||||
|
- StatTrackers
|
||||||
|
- EcoArmor
|
||||||
|
- Illusioner
|
||||||
|
depend:
|
||||||
|
- ProtocolLib
|
||||||
|
softdepend:
|
||||||
|
- WorldGuard
|
||||||
|
- GriefPrevention
|
||||||
|
- Towny
|
||||||
|
- FactionsUUID
|
||||||
|
- Lands
|
||||||
|
- Kingdoms
|
||||||
|
- NoCheatPlus
|
||||||
|
- AAC
|
||||||
|
- Matrix
|
||||||
|
- Spartan
|
||||||
|
- PlaceholderAPI
|
||||||
|
- mcMMO
|
||||||
2
eco-core/core-proxy/build.gradle
Normal file
2
eco-core/core-proxy/build.gradle
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
group 'com.willfp'
|
||||||
|
version rootProject.version
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.willfp.eco.proxy.proxies;
|
||||||
|
|
||||||
|
import com.willfp.eco.util.proxy.AbstractProxy;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public interface AutoCraftProxy extends AbstractProxy {
|
||||||
|
/**
|
||||||
|
* Fix crafting inventory on auto-recipe.
|
||||||
|
*
|
||||||
|
* @param packet The packet to modify.
|
||||||
|
*/
|
||||||
|
void modifyPacket(@NotNull Object packet) throws NoSuchFieldException, IllegalAccessException;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.willfp.eco.proxy.proxies;
|
||||||
|
|
||||||
|
|
||||||
|
import com.willfp.eco.util.proxy.AbstractProxy;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public interface ChatComponentProxy extends AbstractProxy {
|
||||||
|
/**
|
||||||
|
* Modify hover {@link org.bukkit.inventory.ItemStack}s using EnchantDisplay#displayEnchantments.
|
||||||
|
* @param object The NMS ChatComponent to modify.
|
||||||
|
* @return The modified ChatComponent.
|
||||||
|
*/
|
||||||
|
Object modifyComponent(@NotNull Object object);
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.willfp.eco.proxy.proxies;
|
||||||
|
|
||||||
|
import com.willfp.eco.util.proxy.AbstractProxy;
|
||||||
|
import org.bukkit.inventory.MerchantRecipe;
|
||||||
|
|
||||||
|
public interface VillagerTradeProxy extends AbstractProxy {
|
||||||
|
/**
|
||||||
|
* Apply enchant display to the result of trades.
|
||||||
|
*
|
||||||
|
* @param merchantRecipe The recipe to modify.
|
||||||
|
*/
|
||||||
|
void displayTrade(MerchantRecipe merchantRecipe);
|
||||||
|
}
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
package com.willfp.eco.util.proxy;
|
package com.willfp.eco.proxy.util;
|
||||||
|
|
||||||
import com.willfp.eco.util.internal.PluginDependent;
|
import com.willfp.eco.util.internal.PluginDependent;
|
||||||
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
|
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
|
||||||
|
import com.willfp.eco.util.proxy.AbstractProxy;
|
||||||
|
import com.willfp.eco.util.proxy.ProxyConstants;
|
||||||
|
import com.willfp.eco.util.proxy.UnsupportedVersionException;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.IdentityHashMap;
|
import java.util.IdentityHashMap;
|
||||||
24
eco-util/build.gradle
Normal file
24
eco-util/build.gradle
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
group 'com.willfp'
|
||||||
|
version rootProject.version
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compileOnly 'org.apache.maven:maven-artifact:3.0.3'
|
||||||
|
compileOnly 'org.bstats:bstats-bukkit:1.7'
|
||||||
|
compileOnly 'com.comphenix.protocol:ProtocolLib:4.6.0-SNAPSHOT'
|
||||||
|
compileOnly 'me.clip:placeholderapi:2.10.9'
|
||||||
|
}
|
||||||
|
|
||||||
|
compileJava.options.encoding = 'UTF-8'
|
||||||
|
compileJava.dependsOn clean
|
||||||
|
|
||||||
|
build.dependsOn publishToMavenLocal
|
||||||
|
|
||||||
|
publishing {
|
||||||
|
publications {
|
||||||
|
shadow(MavenPublication) {
|
||||||
|
from components.java
|
||||||
|
artifact shadowJar
|
||||||
|
artifactId 'eco'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ package com.willfp.eco.util;
|
|||||||
|
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
import org.bukkit.SoundCategory;
|
import org.bukkit.SoundCategory;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@@ -37,12 +38,20 @@ public class DurabilityUtils {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(item.getItemMeta() instanceof Damageable)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Special edge case
|
||||||
|
if (item.getType() == Material.CARVED_PUMPKIN || item.getType() == Material.PLAYER_HEAD) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
PlayerItemDamageEvent event3 = new PlayerItemDamageEvent(player, item, damage);
|
PlayerItemDamageEvent event3 = new PlayerItemDamageEvent(player, item, damage);
|
||||||
Bukkit.getPluginManager().callEvent(event3);
|
Bukkit.getPluginManager().callEvent(event3);
|
||||||
|
|
||||||
if (!event3.isCancelled()) {
|
if (!event3.isCancelled()) {
|
||||||
int damage2 = event3.getDamage();
|
int damage2 = event3.getDamage();
|
||||||
if (item.getItemMeta() instanceof Damageable) {
|
|
||||||
Damageable meta = (Damageable) item.getItemMeta();
|
Damageable meta = (Damageable) item.getItemMeta();
|
||||||
meta.setDamage(meta.getDamage() + damage2);
|
meta.setDamage(meta.getDamage() + damage2);
|
||||||
|
|
||||||
@@ -58,7 +67,6 @@ public class DurabilityUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Damage an item in a player's inventory without breaking it.
|
* Damage an item in a player's inventory without breaking it.
|
||||||
@@ -78,12 +86,15 @@ public class DurabilityUtils {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(item.getItemMeta() instanceof Damageable)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
PlayerItemDamageEvent event3 = new PlayerItemDamageEvent(player, item, damage);
|
PlayerItemDamageEvent event3 = new PlayerItemDamageEvent(player, item, damage);
|
||||||
Bukkit.getPluginManager().callEvent(event3);
|
Bukkit.getPluginManager().callEvent(event3);
|
||||||
|
|
||||||
if (!event3.isCancelled()) {
|
if (!event3.isCancelled()) {
|
||||||
int damage2 = event3.getDamage();
|
int damage2 = event3.getDamage();
|
||||||
if (item.getItemMeta() instanceof Damageable) {
|
|
||||||
Damageable meta = (Damageable) item.getItemMeta();
|
Damageable meta = (Damageable) item.getItemMeta();
|
||||||
meta.setDamage(meta.getDamage() + damage2);
|
meta.setDamage(meta.getDamage() + damage2);
|
||||||
|
|
||||||
@@ -93,7 +104,6 @@ public class DurabilityUtils {
|
|||||||
item.setItemMeta((ItemMeta) meta);
|
item.setItemMeta((ItemMeta) meta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Repair an item in a player's inventory.
|
* Repair an item in a player's inventory.
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
package com.willfp.eco.util;
|
package com.willfp.eco.util;
|
||||||
|
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
@@ -85,6 +87,24 @@ public class NumberUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get number from roman numeral.
|
||||||
|
*
|
||||||
|
* @param numeral The numeral to convert.
|
||||||
|
* @return The number, converted from a roman numeral.
|
||||||
|
*/
|
||||||
|
public static int fromNumeral(@NotNull final String numeral) {
|
||||||
|
if (numeral.isEmpty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for (Map.Entry<Integer, String> entry : NUMERALS.entrySet()) {
|
||||||
|
if (numeral.startsWith(entry.getValue())) {
|
||||||
|
return entry.getKey() + fromNumeral(numeral.substring(entry.getValue().length()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate random integer in range.
|
* Generate random integer in range.
|
||||||
*
|
*
|
||||||
204
eco-util/src/main/java/com/willfp/eco/util/StringUtils.java
Normal file
204
eco-util/src/main/java/com/willfp/eco/util/StringUtils.java
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
package com.willfp.eco.util;
|
||||||
|
|
||||||
|
import com.willfp.eco.util.integrations.placeholder.PlaceholderManager;
|
||||||
|
import com.willfp.eco.util.optional.Prerequisite;
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static net.md_5.bungee.api.ChatColor.COLOR_CHAR;
|
||||||
|
|
||||||
|
@UtilityClass
|
||||||
|
public class StringUtils {
|
||||||
|
/**
|
||||||
|
* Regex for gradients.
|
||||||
|
*/
|
||||||
|
private static final Pattern GRADIENT_REGEX = Pattern.compile("<GRADIENT:([0-9A-Fa-f]{6})>(.*?)</GRADIENT:([0-9A-Fa-f]{6})>");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Regex for hex codes.
|
||||||
|
*/
|
||||||
|
private static final Pattern HEX_PATTERN = Pattern.compile("&#" + "([A-Fa-f0-9]{6})" + "");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translate a string - converts Placeholders and Color codes.
|
||||||
|
*
|
||||||
|
* @param message The message to translate.
|
||||||
|
* @param player The player to translate placeholders with respect to.
|
||||||
|
* @return The message, translated.
|
||||||
|
*/
|
||||||
|
public String translate(@NotNull final String message,
|
||||||
|
@Nullable final Player player) {
|
||||||
|
String processedMessage = message;
|
||||||
|
if (Prerequisite.MINIMUM_1_16.isMet()) {
|
||||||
|
processedMessage = translateGradients(processedMessage);
|
||||||
|
}
|
||||||
|
processedMessage = PlaceholderManager.translatePlaceholders(processedMessage, player);
|
||||||
|
processedMessage = translateHexColorCodes(processedMessage);
|
||||||
|
processedMessage = ChatColor.translateAlternateColorCodes('&', processedMessage);
|
||||||
|
return processedMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translate a string without respect to a player.
|
||||||
|
*
|
||||||
|
* @param message The message to translate.
|
||||||
|
* @return The message, translated.
|
||||||
|
* @see StringUtils#translate(String, Player)
|
||||||
|
*/
|
||||||
|
public String translate(@NotNull final String message) {
|
||||||
|
return translate(message, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String translateHexColorCodes(@NotNull final String message) {
|
||||||
|
Matcher matcher = HEX_PATTERN.matcher(message);
|
||||||
|
StringBuffer buffer = new StringBuffer(message.length() + 4 * 8);
|
||||||
|
while (matcher.find()) {
|
||||||
|
String group = matcher.group(1);
|
||||||
|
matcher.appendReplacement(buffer, COLOR_CHAR + "x"
|
||||||
|
+ COLOR_CHAR + group.charAt(0) + COLOR_CHAR + group.charAt(1)
|
||||||
|
+ COLOR_CHAR + group.charAt(2) + COLOR_CHAR + group.charAt(3)
|
||||||
|
+ COLOR_CHAR + group.charAt(4) + COLOR_CHAR + group.charAt(5));
|
||||||
|
}
|
||||||
|
|
||||||
|
return matcher.appendTail(buffer).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Colors a string with a gradient.
|
||||||
|
*
|
||||||
|
* @param string The string to color.
|
||||||
|
* @param start The start color.
|
||||||
|
* @param end The end color.
|
||||||
|
* @return The string, colored.
|
||||||
|
*/
|
||||||
|
private static String processGradients(@NotNull final String string,
|
||||||
|
@NotNull final Color start,
|
||||||
|
@NotNull final Color end) {
|
||||||
|
String processedString = string;
|
||||||
|
List<ChatColor> modifiers = new ArrayList<>();
|
||||||
|
if (processedString.contains("&l")) {
|
||||||
|
modifiers.add(ChatColor.BOLD);
|
||||||
|
}
|
||||||
|
if (processedString.contains("&o")) {
|
||||||
|
modifiers.add(ChatColor.ITALIC);
|
||||||
|
}
|
||||||
|
if (processedString.contains("&n")) {
|
||||||
|
modifiers.add(ChatColor.UNDERLINE);
|
||||||
|
}
|
||||||
|
if (processedString.contains("&k")) {
|
||||||
|
modifiers.add(ChatColor.MAGIC);
|
||||||
|
}
|
||||||
|
processedString = processedString.replace("&l", "");
|
||||||
|
processedString = processedString.replace("&o", "");
|
||||||
|
processedString = processedString.replace("&n", "");
|
||||||
|
processedString = processedString.replace("&k", "");
|
||||||
|
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
ChatColor[] colors = getGradientColors(start, end, processedString.length());
|
||||||
|
String[] characters = processedString.split("");
|
||||||
|
for (int i = 0; i < processedString.length(); i++) {
|
||||||
|
stringBuilder.append(colors[i]);
|
||||||
|
modifiers.forEach(stringBuilder::append);
|
||||||
|
stringBuilder.append(characters[i]);
|
||||||
|
}
|
||||||
|
return stringBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates chatColors for gradients.
|
||||||
|
*
|
||||||
|
* @param start The start color.
|
||||||
|
* @param end The end color.
|
||||||
|
* @param step How many colors are returned.
|
||||||
|
* @return Array of chat colors.
|
||||||
|
*/
|
||||||
|
private static ChatColor[] getGradientColors(@NotNull final Color start,
|
||||||
|
@NotNull final Color end,
|
||||||
|
final int step) {
|
||||||
|
ChatColor[] colors = new ChatColor[step];
|
||||||
|
int stepR = Math.abs(start.getRed() - end.getRed()) / (step - 1);
|
||||||
|
int stepG = Math.abs(start.getGreen() - end.getGreen()) / (step - 1);
|
||||||
|
int stepB = Math.abs(start.getBlue() - end.getBlue()) / (step - 1);
|
||||||
|
int[] direction = new int[]{
|
||||||
|
start.getRed() < end.getRed() ? +1 : -1,
|
||||||
|
start.getGreen() < end.getGreen() ? +1 : -1,
|
||||||
|
start.getBlue() < end.getBlue() ? +1 : -1
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i < step; i++) {
|
||||||
|
Color color = new Color(start.getRed() + ((stepR * i) * direction[0]), start.getGreen() + ((stepG * i) * direction[1]), start.getBlue() + ((stepB * i) * direction[2]));
|
||||||
|
colors[i] = ChatColor.of(color);
|
||||||
|
}
|
||||||
|
return colors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add gradients to a string.
|
||||||
|
*
|
||||||
|
* @param string The string.
|
||||||
|
* @return The string, colorized.
|
||||||
|
*/
|
||||||
|
private static String translateGradients(@NotNull final String string) {
|
||||||
|
String processedString = string;
|
||||||
|
Matcher matcher = GRADIENT_REGEX.matcher(string);
|
||||||
|
while (matcher.find()) {
|
||||||
|
String start = matcher.group(1);
|
||||||
|
String end = matcher.group(3);
|
||||||
|
String content = matcher.group(2);
|
||||||
|
processedString = processedString.replace(matcher.group(), processGradients(content, new Color(Integer.parseInt(start, 16)), new Color(Integer.parseInt(end, 16))));
|
||||||
|
}
|
||||||
|
return processedString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal implementation of {@link String#valueOf}.
|
||||||
|
* Formats collections and doubles better.
|
||||||
|
*
|
||||||
|
* @param object The object to convert to string.
|
||||||
|
* @return The object stringified.
|
||||||
|
*/
|
||||||
|
public String internalToString(@Nullable final Object object) {
|
||||||
|
if (object == null) {
|
||||||
|
return "null";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (object instanceof Integer) {
|
||||||
|
return ((Integer) object).toString();
|
||||||
|
} else if (object instanceof String) {
|
||||||
|
return (String) object;
|
||||||
|
} else if (object instanceof Double) {
|
||||||
|
return NumberUtils.format((Double) object);
|
||||||
|
} else if (object instanceof Collection<?>) {
|
||||||
|
Collection<?> c = (Collection<?>) object;
|
||||||
|
return c.stream().map(StringUtils::internalToString).collect(Collectors.joining(", "));
|
||||||
|
} else {
|
||||||
|
return String.valueOf(object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a string of characters from the start of a string.
|
||||||
|
*
|
||||||
|
* @param string The string to remove the prefix from.
|
||||||
|
* @param prefix The substring to remove.
|
||||||
|
* @return The string with the prefix removed.
|
||||||
|
*/
|
||||||
|
public String removePrefix(@NotNull final String string,
|
||||||
|
@NotNull final String prefix) {
|
||||||
|
if (string.startsWith(prefix)) {
|
||||||
|
return string.substring(prefix.length());
|
||||||
|
}
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,9 +6,16 @@ import org.bukkit.util.Vector;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@UtilityClass
|
@UtilityClass
|
||||||
public class VectorUtils {
|
public class VectorUtils {
|
||||||
|
/**
|
||||||
|
* Cached circles to prevent many sqrt calls.
|
||||||
|
*/
|
||||||
|
private static final Map<Integer, Vector[]> CIRCLE_CACHE = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If vector has all components as finite.
|
* If vector has all components as finite.
|
||||||
*
|
*
|
||||||
@@ -66,6 +73,11 @@ public class VectorUtils {
|
|||||||
* @return An array of {@link Vector}s.
|
* @return An array of {@link Vector}s.
|
||||||
*/
|
*/
|
||||||
public Vector[] getCircle(final int radius) {
|
public Vector[] getCircle(final int radius) {
|
||||||
|
Vector[] cached = CIRCLE_CACHE.get(radius);
|
||||||
|
if (cached != null) {
|
||||||
|
return cached;
|
||||||
|
}
|
||||||
|
|
||||||
ArrayList<Vector> circleVecs = new ArrayList<>();
|
ArrayList<Vector> circleVecs = new ArrayList<>();
|
||||||
|
|
||||||
double xoffset = -radius;
|
double xoffset = -radius;
|
||||||
@@ -85,7 +97,9 @@ public class VectorUtils {
|
|||||||
zoffset++;
|
zoffset++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return circleVecs.toArray(new Vector[0]);
|
Vector[] result = circleVecs.toArray(new Vector[0]);
|
||||||
|
CIRCLE_CACHE.put(radius, result);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -11,8 +11,6 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
public class EcoEventManager extends PluginDependent implements EventManager {
|
public class EcoEventManager extends PluginDependent implements EventManager {
|
||||||
/**
|
/**
|
||||||
* Manager class for event management.
|
* Manager class for event management.
|
||||||
* <p>
|
|
||||||
* Prevents calls to {@link AbstractEcoPlugin#getInstance()}.
|
|
||||||
*
|
*
|
||||||
* @param plugin The {@link AbstractEcoPlugin} that this manages the events of.
|
* @param plugin The {@link AbstractEcoPlugin} that this manages the events of.
|
||||||
*/
|
*/
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.willfp.eco.util.command;
|
package com.willfp.eco.util.command;
|
||||||
|
|
||||||
import com.willfp.eco.util.config.Configs;
|
|
||||||
import com.willfp.eco.util.internal.PluginDependent;
|
import com.willfp.eco.util.internal.PluginDependent;
|
||||||
import com.willfp.eco.util.interfaces.Registerable;
|
import com.willfp.eco.util.interfaces.Registerable;
|
||||||
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
|
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
|
||||||
@@ -112,12 +111,12 @@ public abstract class AbstractCommand extends PluginDependent implements Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (playersOnly && !(sender instanceof Player)) {
|
if (playersOnly && !(sender instanceof Player)) {
|
||||||
sender.sendMessage(Configs.LANG.getMessage("not-player"));
|
sender.sendMessage(this.getPlugin().getLangYml().getMessage("not-player"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sender.hasPermission(permission) && sender instanceof Player) {
|
if (!sender.hasPermission(permission) && sender instanceof Player) {
|
||||||
sender.sendMessage(Configs.LANG.getNoPermission());
|
sender.sendMessage(this.getPlugin().getLangYml().getNoPermission());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package com.willfp.eco.util.config;
|
||||||
|
|
||||||
|
import com.willfp.eco.util.config.internal.AbstractUpdatableConfig;
|
||||||
|
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public abstract class BaseConfig extends AbstractUpdatableConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
|
||||||
|
* <p>
|
||||||
|
* Automatically updates.
|
||||||
|
*
|
||||||
|
* @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 BaseConfig(@NotNull final String configName,
|
||||||
|
final boolean removeUnused,
|
||||||
|
@NotNull final AbstractEcoPlugin plugin,
|
||||||
|
@NotNull final String... updateBlacklist) {
|
||||||
|
super(configName, plugin, "", plugin.getClass(), removeUnused, updateBlacklist);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
|
||||||
|
* <p>
|
||||||
|
* Automatically updates.
|
||||||
|
*
|
||||||
|
* @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 BaseConfig(@NotNull final String configName,
|
||||||
|
final boolean removeUnused,
|
||||||
|
@NotNull final AbstractEcoPlugin plugin) {
|
||||||
|
super(configName, plugin, "", plugin.getClass(), removeUnused, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.willfp.eco.util.config;
|
||||||
|
|
||||||
|
import com.willfp.eco.util.config.internal.AbstractUpdatableConfig;
|
||||||
|
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public abstract class ExtendableConfig extends AbstractUpdatableConfig {
|
||||||
|
/**
|
||||||
|
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
|
||||||
|
* <p>
|
||||||
|
* Automatically updates.
|
||||||
|
*
|
||||||
|
* @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 ExtendableConfig(@NotNull final String configName,
|
||||||
|
final boolean removeUnused,
|
||||||
|
@NotNull final AbstractEcoPlugin plugin,
|
||||||
|
@NotNull final Class<?> source,
|
||||||
|
@NotNull final String subDirectoryPath,
|
||||||
|
@NotNull final String... updateBlacklist) {
|
||||||
|
super(configName, plugin, subDirectoryPath, source, removeUnused, updateBlacklist);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.willfp.eco.util.config;
|
||||||
|
|
||||||
|
import com.willfp.eco.util.config.internal.AbstractConfig;
|
||||||
|
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public abstract class StaticBaseConfig extends AbstractConfig {
|
||||||
|
/**
|
||||||
|
* 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 StaticBaseConfig(@NotNull final String configName,
|
||||||
|
@NotNull final AbstractEcoPlugin plugin) {
|
||||||
|
super(configName, plugin, "", plugin.getClass());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package com.willfp.eco.util.config;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public interface ValueGetter {
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.willfp.eco.util.config.configs;
|
||||||
|
|
||||||
|
import com.willfp.eco.util.config.BaseConfig;
|
||||||
|
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
|
||||||
|
public class Config extends BaseConfig {
|
||||||
|
/**
|
||||||
|
* Config.yml.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin.
|
||||||
|
*/
|
||||||
|
public Config(@NotNull final AbstractEcoPlugin plugin) {
|
||||||
|
super("config", true, plugin);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,14 +2,17 @@ package com.willfp.eco.util.config.configs;
|
|||||||
|
|
||||||
import com.willfp.eco.util.StringUtils;
|
import com.willfp.eco.util.StringUtils;
|
||||||
import com.willfp.eco.util.config.BaseConfig;
|
import com.willfp.eco.util.config.BaseConfig;
|
||||||
|
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class Lang extends BaseConfig {
|
public class Lang extends BaseConfig {
|
||||||
/**
|
/**
|
||||||
* lang.yml.
|
* Lang.yml.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin.
|
||||||
*/
|
*/
|
||||||
public Lang() {
|
public Lang(@NotNull final AbstractEcoPlugin plugin) {
|
||||||
super("lang", false);
|
super("lang", false, plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -0,0 +1,407 @@
|
|||||||
|
package com.willfp.eco.util.config.internal;
|
||||||
|
|
||||||
|
import com.willfp.eco.util.StringUtils;
|
||||||
|
import com.willfp.eco.util.internal.PluginDependent;
|
||||||
|
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.bukkit.configuration.InvalidConfigurationException;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public abstract class AbstractConfig extends PluginDependent {
|
||||||
|
/**
|
||||||
|
* The linked {@link YamlConfiguration} where values are physically stored.
|
||||||
|
*/
|
||||||
|
@Getter(AccessLevel.PUBLIC)
|
||||||
|
protected final YamlConfiguration config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The physical config file, as stored on disk.
|
||||||
|
*/
|
||||||
|
@Getter(AccessLevel.PROTECTED)
|
||||||
|
private final File configFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The full name of the config file (eg config.yml).
|
||||||
|
*/
|
||||||
|
@Getter(AccessLevel.PROTECTED)
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The subdirectory path.
|
||||||
|
*/
|
||||||
|
@Getter(AccessLevel.PROTECTED)
|
||||||
|
private final String subDirectoryPath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The provider of the config.
|
||||||
|
*/
|
||||||
|
@Getter(AccessLevel.PROTECTED)
|
||||||
|
private final Class<?> source;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract config.
|
||||||
|
*
|
||||||
|
* @param configName The name of the config
|
||||||
|
* @param plugin The plugin.
|
||||||
|
* @param subDirectoryPath The subdirectory path.
|
||||||
|
* @param source The class that owns the resource.
|
||||||
|
*/
|
||||||
|
protected AbstractConfig(@NotNull final String configName,
|
||||||
|
@NotNull final AbstractEcoPlugin plugin,
|
||||||
|
@NotNull final String subDirectoryPath,
|
||||||
|
@NotNull final Class<?> source) {
|
||||||
|
super(plugin);
|
||||||
|
this.source = source;
|
||||||
|
this.subDirectoryPath = subDirectoryPath;
|
||||||
|
this.name = configName + ".yml";
|
||||||
|
|
||||||
|
File directory = new File(this.getPlugin().getDataFolder(), subDirectoryPath);
|
||||||
|
if (!directory.exists()) {
|
||||||
|
directory.mkdirs();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!new File(directory, this.name).exists()) {
|
||||||
|
createFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.configFile = new File(directory, this.name);
|
||||||
|
this.config = YamlConfiguration.loadConfiguration(configFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createFile() {
|
||||||
|
String resourcePath = getResourcePath();
|
||||||
|
InputStream in = source.getResourceAsStream(resourcePath);
|
||||||
|
|
||||||
|
File outFile = new File(this.getPlugin().getDataFolder(), resourcePath);
|
||||||
|
int lastIndex = resourcePath.lastIndexOf('/');
|
||||||
|
File outDir = new File(this.getPlugin().getDataFolder(), resourcePath.substring(0, Math.max(lastIndex, 0)));
|
||||||
|
|
||||||
|
if (!outDir.exists()) {
|
||||||
|
outDir.mkdirs();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!outFile.exists()) {
|
||||||
|
OutputStream out = new FileOutputStream(outFile);
|
||||||
|
byte[] buf = new byte[1024];
|
||||||
|
int len;
|
||||||
|
while ((len = in.read(buf)) > 0) {
|
||||||
|
out.write(buf, 0, len);
|
||||||
|
}
|
||||||
|
out.close();
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get resource path as relative to base directory.
|
||||||
|
*
|
||||||
|
* @return The resource path.
|
||||||
|
*/
|
||||||
|
protected String getResourcePath() {
|
||||||
|
String resourcePath;
|
||||||
|
|
||||||
|
if (subDirectoryPath.isEmpty()) {
|
||||||
|
resourcePath = name;
|
||||||
|
} else {
|
||||||
|
resourcePath = subDirectoryPath + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "/" + resourcePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get YamlConfiguration as found in jar.
|
||||||
|
*
|
||||||
|
* @return The YamlConfiguration.
|
||||||
|
*/
|
||||||
|
protected YamlConfiguration getConfigInJar() {
|
||||||
|
InputStream newIn = source.getResourceAsStream(getResourcePath());
|
||||||
|
|
||||||
|
if (newIn == null) {
|
||||||
|
throw new NullPointerException(this.getName() + " is null?");
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(newIn, StandardCharsets.UTF_8));
|
||||||
|
YamlConfiguration newConfig = new YamlConfiguration();
|
||||||
|
|
||||||
|
try {
|
||||||
|
newConfig.load(reader);
|
||||||
|
} catch (IOException | InvalidConfigurationException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return newConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if the config contains a key.
|
||||||
|
*
|
||||||
|
* @param path The key to check.
|
||||||
|
* @return If contained.
|
||||||
|
*/
|
||||||
|
public boolean has(@NotNull final String path) {
|
||||||
|
return config.contains(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get configuration section from config.
|
||||||
|
*
|
||||||
|
* @param path The key to check.
|
||||||
|
* @return The configuration section. Throws NPE if not found.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public ConfigurationSection getSection(@NotNull final String path) {
|
||||||
|
ConfigurationSection section = getSectionOrNull(path);
|
||||||
|
if (section == null) {
|
||||||
|
throw new NullPointerException("Section cannot be null!");
|
||||||
|
} else {
|
||||||
|
return section;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get configuration section from config.
|
||||||
|
*
|
||||||
|
* @param path The key to check.
|
||||||
|
* @return The configuration section, or null if not found.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public ConfigurationSection getSectionOrNull(@NotNull final String path) {
|
||||||
|
return config.getConfigurationSection(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an integer from config.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The found value, or 0 if not found.
|
||||||
|
*/
|
||||||
|
public int getInt(@NotNull final String path) {
|
||||||
|
return config.getInt(path, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an integer from config.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The found value, or null if not found.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public Integer getIntOrNull(@NotNull final String path) {
|
||||||
|
if (has(path)) {
|
||||||
|
return getInt(path);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an integer from config with a specified default (not found) value.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @param def The value to default to if not found.
|
||||||
|
* @return The found value, or the default.
|
||||||
|
*/
|
||||||
|
public int getInt(@NotNull final String path,
|
||||||
|
final int def) {
|
||||||
|
return config.getInt(path, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of integers from config.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public List<Integer> getInts(@NotNull final String path) {
|
||||||
|
return config.getIntegerList(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of integers from config.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The found value, or null if not found.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public List<Integer> getIntsOrNull(@NotNull final String path) {
|
||||||
|
if (has(path)) {
|
||||||
|
return getInts(path);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a boolean from config.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The found value, or false if not found.
|
||||||
|
*/
|
||||||
|
public boolean getBool(@NotNull final String path) {
|
||||||
|
return config.getBoolean(path, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a boolean from config.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The found value, or null if not found.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public Boolean getBoolOrNull(@NotNull final String path) {
|
||||||
|
if (has(path)) {
|
||||||
|
return getBool(path);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of booleans from config.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public List<Boolean> getBools(@NotNull final String path) {
|
||||||
|
return config.getBooleanList(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of booleans from config.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The found value, or null if not found.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public List<Boolean> getBoolsOrNull(@NotNull final String path) {
|
||||||
|
if (has(path)) {
|
||||||
|
return getBools(path);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a string from config.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The found value, or an empty string if not found.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public String getString(@NotNull final String path) {
|
||||||
|
return StringUtils.translate(Objects.requireNonNull(config.getString(path, "")));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a string from config.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The found value, or null if not found.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public String getStringOrNull(@NotNull final String path) {
|
||||||
|
if (has(path)) {
|
||||||
|
return getString(path);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of strings from config.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public List<String> getStrings(@NotNull final String path) {
|
||||||
|
return config.getStringList(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of strings from config.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The found value, or null if not found.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public List<String> getStringsOrNull(@NotNull final String path) {
|
||||||
|
if (has(path)) {
|
||||||
|
return getStrings(path);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a decimal from config.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The found value, or 0 if not found.
|
||||||
|
*/
|
||||||
|
public double getDouble(@NotNull final String path) {
|
||||||
|
return config.getDouble(path, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a decimal from config.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The found value, or null if not found.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public Double getDoubleOrNull(@NotNull final String path) {
|
||||||
|
if (has(path)) {
|
||||||
|
return getDouble(path);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of decimals from config.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public List<Double> getDoubles(@NotNull final String path) {
|
||||||
|
return config.getDoubleList(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of decimals from config.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The found value, or null if not found.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public List<Double> getDoublesOrNull(@NotNull final String path) {
|
||||||
|
if (has(path)) {
|
||||||
|
return getDoubles(path);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
package com.willfp.eco.util.config.internal;
|
||||||
|
|
||||||
|
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
|
||||||
|
import org.bukkit.configuration.InvalidConfigurationException;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public abstract class AbstractUpdatableConfig extends AbstractConfig {
|
||||||
|
/**
|
||||||
|
* Whether keys not in the base config should be removed on update.
|
||||||
|
*/
|
||||||
|
private final boolean removeUnused;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of blacklisted update keys.
|
||||||
|
*/
|
||||||
|
private final List<String> updateBlacklist;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updatable config.
|
||||||
|
*
|
||||||
|
* @param configName The name of the config
|
||||||
|
* @param plugin The plugin.
|
||||||
|
* @param subDirectoryPath The subdirectory path.
|
||||||
|
* @param source The class that owns the resource.
|
||||||
|
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||||
|
* @param updateBlacklist Substring of keys to not add/remove keys for.
|
||||||
|
*/
|
||||||
|
protected AbstractUpdatableConfig(@NotNull final String configName,
|
||||||
|
@NotNull final AbstractEcoPlugin plugin,
|
||||||
|
@NotNull final String subDirectoryPath,
|
||||||
|
@NotNull final Class<?> source,
|
||||||
|
final boolean removeUnused,
|
||||||
|
@NotNull final String... updateBlacklist) {
|
||||||
|
super(configName, plugin, subDirectoryPath, source);
|
||||||
|
this.removeUnused = removeUnused;
|
||||||
|
this.updateBlacklist = new ArrayList<>(Arrays.asList(updateBlacklist));
|
||||||
|
this.updateBlacklist.removeIf(String::isEmpty);
|
||||||
|
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the config.
|
||||||
|
* <p>
|
||||||
|
* Writes missing values, however removes comments due to how configs are stored internally in bukkit.
|
||||||
|
*/
|
||||||
|
public void update() {
|
||||||
|
try {
|
||||||
|
config.load(this.getConfigFile());
|
||||||
|
|
||||||
|
YamlConfiguration newConfig = this.getConfigInJar();
|
||||||
|
|
||||||
|
if (newConfig.getKeys(true).equals(config.getKeys(true))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
newConfig.getKeys(true).forEach((s -> {
|
||||||
|
if (!config.getKeys(true).contains(s)) {
|
||||||
|
if (updateBlacklist.stream().noneMatch(s::contains)) {
|
||||||
|
config.set(s, newConfig.get(s));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (this.removeUnused) {
|
||||||
|
config.getKeys(true).forEach((s -> {
|
||||||
|
if (!newConfig.getKeys(true).contains(s)) {
|
||||||
|
if (updateBlacklist.stream().noneMatch(s::contains)) {
|
||||||
|
config.set(s, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
config.save(this.getConfigFile());
|
||||||
|
} catch (IOException | InvalidConfigurationException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
218
eco-util/src/main/java/com/willfp/eco/util/display/Display.java
Normal file
218
eco-util/src/main/java/com/willfp/eco/util/display/Display.java
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
package com.willfp.eco.util.display;
|
||||||
|
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.bukkit.persistence.PersistentDataContainer;
|
||||||
|
import org.bukkit.persistence.PersistentDataType;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
@UtilityClass
|
||||||
|
public class Display {
|
||||||
|
/**
|
||||||
|
* Registered display functions.
|
||||||
|
*/
|
||||||
|
private static final List<Map<String, Function<ItemStack, ItemStack>>> DISPLAY_FUNCTIONS = new ArrayList<>(10000);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registered revert functions.
|
||||||
|
*/
|
||||||
|
private static final List<Function<ItemStack, ItemStack>> REVERT_FUNCTIONS = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NamespacedKey for finalizing.
|
||||||
|
*/
|
||||||
|
private static NamespacedKey finalizeKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register display module.
|
||||||
|
*
|
||||||
|
* @param module The module.
|
||||||
|
*/
|
||||||
|
public void registerDisplayModule(@NotNull final DisplayModule module) {
|
||||||
|
int priority = module.getPriority();
|
||||||
|
if (priority > 9999) {
|
||||||
|
priority = 9999;
|
||||||
|
}
|
||||||
|
Function<ItemStack, ItemStack> function = module.getFunction();
|
||||||
|
|
||||||
|
Map<String, Function<ItemStack, ItemStack>> functions = DISPLAY_FUNCTIONS.get(priority);
|
||||||
|
if (functions == null) {
|
||||||
|
functions = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
functions.remove(module.getId());
|
||||||
|
functions.put(module.getId(), function);
|
||||||
|
|
||||||
|
DISPLAY_FUNCTIONS.set(priority, functions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register revert function.
|
||||||
|
*
|
||||||
|
* @param function The function.
|
||||||
|
*/
|
||||||
|
public void registerRevertModule(@NotNull final Function<ItemStack, ItemStack> function) {
|
||||||
|
REVERT_FUNCTIONS.add(function);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display on ItemStacks.
|
||||||
|
*
|
||||||
|
* @param itemStack The item.
|
||||||
|
* @return The itemstack.
|
||||||
|
*/
|
||||||
|
public ItemStack display(@NotNull final ItemStack itemStack) {
|
||||||
|
if (isFinalized(itemStack)) {
|
||||||
|
unfinalize(itemStack);
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
revert(itemStack);
|
||||||
|
|
||||||
|
for (Map<String, Function<ItemStack, ItemStack>> displayFunctions : DISPLAY_FUNCTIONS) {
|
||||||
|
if (displayFunctions == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Function<ItemStack, ItemStack> displayFunction : displayFunctions.values()) {
|
||||||
|
displayFunction.apply(itemStack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display on ItemStacks and then finalize.
|
||||||
|
*
|
||||||
|
* @param itemStack The item.
|
||||||
|
* @return The itemstack.
|
||||||
|
*/
|
||||||
|
public ItemStack displayAndFinalize(@NotNull final ItemStack itemStack) {
|
||||||
|
return finalize(display(itemStack));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Revert on ItemStacks.
|
||||||
|
*
|
||||||
|
* @param itemStack The item.
|
||||||
|
* @return The itemstack.
|
||||||
|
*/
|
||||||
|
public ItemStack revert(@NotNull final ItemStack itemStack) {
|
||||||
|
if (isFinalized(itemStack)) {
|
||||||
|
unfinalize(itemStack);
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Function<ItemStack, ItemStack> displayFunction : REVERT_FUNCTIONS) {
|
||||||
|
displayFunction.apply(itemStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finalize an ItemStacks.
|
||||||
|
*
|
||||||
|
* @param itemStack The item.
|
||||||
|
* @return The itemstack.
|
||||||
|
*/
|
||||||
|
public ItemStack finalize(@NotNull final ItemStack itemStack) {
|
||||||
|
Validate.notNull(finalizeKey, "Key cannot be null!");
|
||||||
|
if (itemStack.getType().getMaxStackSize() > 1) {
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
ItemMeta meta = itemStack.getItemMeta();
|
||||||
|
if (meta == null) {
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
PersistentDataContainer container = meta.getPersistentDataContainer();
|
||||||
|
container.set(finalizeKey, PersistentDataType.INTEGER, 1);
|
||||||
|
itemStack.setItemMeta(meta);
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unfinalize an ItemStacks.
|
||||||
|
*
|
||||||
|
* @param itemStack The item.
|
||||||
|
* @return The itemstack.
|
||||||
|
*/
|
||||||
|
public ItemStack unfinalize(@NotNull final ItemStack itemStack) {
|
||||||
|
Validate.notNull(finalizeKey, "Key cannot be null!");
|
||||||
|
ItemMeta meta = itemStack.getItemMeta();
|
||||||
|
if (meta == null) {
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
PersistentDataContainer container = meta.getPersistentDataContainer();
|
||||||
|
container.remove(finalizeKey);
|
||||||
|
itemStack.setItemMeta(meta);
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If an item is finalized.
|
||||||
|
*
|
||||||
|
* @param itemStack The item.
|
||||||
|
* @return If finalized.
|
||||||
|
*/
|
||||||
|
public boolean isFinalized(@NotNull final ItemStack itemStack) {
|
||||||
|
Validate.notNull(finalizeKey, "Key cannot be null!");
|
||||||
|
ItemMeta meta = itemStack.getItemMeta();
|
||||||
|
if (meta == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
PersistentDataContainer container = meta.getPersistentDataContainer();
|
||||||
|
return container.has(finalizeKey, PersistentDataType.INTEGER);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register finalize function.
|
||||||
|
*
|
||||||
|
* @param function The function.
|
||||||
|
* @deprecated Not needed.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public void registerFinalizeModule(@NotNull final Function<ItemStack, ItemStack> function) {
|
||||||
|
// This function is not needed.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register finalize test function.
|
||||||
|
*
|
||||||
|
* @param function The function.
|
||||||
|
* @deprecated Not needed.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public void registerFinalizeTestModule(@NotNull final Predicate<ItemStack> function) {
|
||||||
|
// This isn't needed.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set key to be used for finalization.
|
||||||
|
*
|
||||||
|
* @param finalizeKey The key.
|
||||||
|
*/
|
||||||
|
@ApiStatus.Internal
|
||||||
|
public static void setFinalizeKey(@NotNull final NamespacedKey finalizeKey) {
|
||||||
|
Display.finalizeKey = finalizeKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
for (int i = 0; i < 10000; i++) {
|
||||||
|
DISPLAY_FUNCTIONS.add(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package com.willfp.eco.util.display;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public class DisplayModule {
|
||||||
|
/**
|
||||||
|
* Priority of the display module, where lower numbers are executed sooner.
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
private final int priority;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The function executed on display.
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
private final Function<ItemStack, ItemStack> function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function id for unregistration.
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
private final String id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new display module.
|
||||||
|
*
|
||||||
|
* @param function The function.
|
||||||
|
* @param priority The priority.
|
||||||
|
* @param id The id.
|
||||||
|
*/
|
||||||
|
public DisplayModule(@NotNull final Function<ItemStack, ItemStack> function,
|
||||||
|
final int priority,
|
||||||
|
@NotNull final String id) {
|
||||||
|
this.function = function;
|
||||||
|
this.priority = priority;
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.willfp.eco.util.drops.internal;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
@UtilityClass
|
||||||
|
public final class DropManager {
|
||||||
|
/**
|
||||||
|
* The currently used type, or implementation, of {@link AbstractDropQueue}.
|
||||||
|
* <p>
|
||||||
|
* Default is {@link DropQueueType#COLLATED}, however this can be changed.
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
private DropQueueType type = DropQueueType.COLLATED;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the type of Drop Queue to be used.
|
||||||
|
*
|
||||||
|
* @param type The type.
|
||||||
|
*/
|
||||||
|
public static void setType(@NotNull final DropQueueType type) {
|
||||||
|
DropManager.type = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.willfp.eco.util.drops.internal;
|
package com.willfp.eco.util.drops.internal;
|
||||||
|
|
||||||
import com.willfp.eco.util.internal.PluginDependent;
|
|
||||||
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
|
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
@@ -13,10 +12,9 @@ import org.bukkit.scheduler.BukkitTask;
|
|||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
public class FastCollatedDropQueue extends InternalDropQueue {
|
public class FastCollatedDropQueue extends InternalDropQueue {
|
||||||
/**
|
/**
|
||||||
@@ -24,7 +22,7 @@ public class FastCollatedDropQueue extends InternalDropQueue {
|
|||||||
* <p>
|
* <p>
|
||||||
* Cleared and updated every tick.
|
* Cleared and updated every tick.
|
||||||
*/
|
*/
|
||||||
private static final HashMap<Player, CollatedDrops> COLLATED_MAP = new HashMap<>();
|
private static final Map<Player, CollatedDrops> COLLATED_MAP = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Backend implementation of {@link AbstractDropQueue}
|
* Backend implementation of {@link AbstractDropQueue}
|
||||||
@@ -104,7 +102,7 @@ public class FastCollatedDropQueue extends InternalDropQueue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class CollatedRunnable extends PluginDependent {
|
public static class CollatedRunnable {
|
||||||
/**
|
/**
|
||||||
* The {@link BukkitTask} that the runnable represents.
|
* The {@link BukkitTask} that the runnable represents.
|
||||||
*/
|
*/
|
||||||
@@ -118,7 +116,6 @@ public class FastCollatedDropQueue extends InternalDropQueue {
|
|||||||
*/
|
*/
|
||||||
@ApiStatus.Internal
|
@ApiStatus.Internal
|
||||||
public CollatedRunnable(@NotNull final AbstractEcoPlugin plugin) {
|
public CollatedRunnable(@NotNull final AbstractEcoPlugin plugin) {
|
||||||
super(plugin);
|
|
||||||
runnableTask = plugin.getScheduler().runTimer(() -> {
|
runnableTask = plugin.getScheduler().runTimer(() -> {
|
||||||
for (Map.Entry<Player, CollatedDrops> entry : COLLATED_MAP.entrySet()) {
|
for (Map.Entry<Player, CollatedDrops> entry : COLLATED_MAP.entrySet()) {
|
||||||
new InternalDropQueue(entry.getKey())
|
new InternalDropQueue(entry.getKey())
|
||||||
@@ -126,6 +123,7 @@ public class FastCollatedDropQueue extends InternalDropQueue {
|
|||||||
.addItems(entry.getValue().getDrops())
|
.addItems(entry.getValue().getDrops())
|
||||||
.addXP(entry.getValue().getXp())
|
.addXP(entry.getValue().getXp())
|
||||||
.push();
|
.push();
|
||||||
|
COLLATED_MAP.remove(entry.getKey());
|
||||||
}
|
}
|
||||||
COLLATED_MAP.clear();
|
COLLATED_MAP.clear();
|
||||||
}, 0, 1);
|
}, 0, 1);
|
||||||
@@ -5,6 +5,7 @@ import lombok.AccessLevel;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.entity.ExperienceOrb;
|
import org.bukkit.entity.ExperienceOrb;
|
||||||
@@ -133,6 +134,11 @@ public class InternalDropQueue implements AbstractDropQueue {
|
|||||||
assert world != null;
|
assert world != null;
|
||||||
loc = loc.add(0.5, 0.5, 0.5);
|
loc = loc.add(0.5, 0.5, 0.5);
|
||||||
|
|
||||||
|
items.removeIf(itemStack -> itemStack.getType() == Material.AIR);
|
||||||
|
if (items.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (hasTelekinesis) {
|
if (hasTelekinesis) {
|
||||||
HashMap<Integer, ItemStack> leftover = player.getInventory().addItem(items.toArray(new ItemStack[0]));
|
HashMap<Integer, ItemStack> leftover = player.getInventory().addItem(items.toArray(new ItemStack[0]));
|
||||||
for (ItemStack drop : leftover.values()) {
|
for (ItemStack drop : leftover.values()) {
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.willfp.eco.util.drops.telekinesis;
|
package com.willfp.eco.util.drops.telekinesis;
|
||||||
|
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
@@ -7,20 +8,20 @@ import java.util.HashSet;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public class EcoTelekinesisTests implements TelekinesisTests {
|
@UtilityClass
|
||||||
|
public final class TelekinesisUtils {
|
||||||
/**
|
/**
|
||||||
* Set of tests that return if the player is telekinetic.
|
* Set of tests that return if the player is telekinetic.
|
||||||
*/
|
*/
|
||||||
private final Set<Function<Player, Boolean>> tests = new HashSet<>();
|
private static final Set<Function<Player, Boolean>> TESTS = new HashSet<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a new test to check against.
|
* Register a new test to check against.
|
||||||
*
|
*
|
||||||
* @param test The test to register, where the boolean output is if the player is telekinetic.
|
* @param test The test to register, where the boolean output is if the player is telekinetic.
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
public void registerTest(@NotNull final Function<Player, Boolean> test) {
|
public void registerTest(@NotNull final Function<Player, Boolean> test) {
|
||||||
tests.add(test);
|
TESTS.add(test);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -31,9 +32,8 @@ public class EcoTelekinesisTests implements TelekinesisTests {
|
|||||||
* @param player The player to test.
|
* @param player The player to test.
|
||||||
* @return If the player is telekinetic.
|
* @return If the player is telekinetic.
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
public boolean testPlayer(@NotNull final Player player) {
|
public boolean testPlayer(@NotNull final Player player) {
|
||||||
for (Function<Player, Boolean> test : tests) {
|
for (Function<Player, Boolean> test : TESTS) {
|
||||||
if (test.apply(player)) {
|
if (test.apply(player)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user