Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f0cd9ae16d | ||
|
|
b220428b8c | ||
|
|
8386aacfd8 | ||
|
|
3c54e24102 | ||
|
|
3dc0693b8c | ||
|
|
f087113ddf | ||
|
|
d5d1f5d8cc | ||
|
|
0d5bf901e2 | ||
|
|
ae0445f47b | ||
|
|
a6ba24b7a5 | ||
|
|
1b00831147 | ||
|
|
479cff60d5 | ||
|
|
d2499b1e27 | ||
|
|
4f65f33953 | ||
|
|
6d4a69c781 | ||
|
|
e90e58b50a | ||
|
|
826bdb63d0 | ||
|
|
4ecba69161 | ||
|
|
e64510ebf5 | ||
|
|
50a506af62 |
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
|
||||||
|
|||||||
148
build.gradle
148
build.gradle
@@ -6,97 +6,91 @@ 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()
|
||||||
maven { url 'https://jitpack.io' }
|
maven { url 'https://jitpack.io' }
|
||||||
|
|
||||||
// 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
|
||||||
maven { url 'https://repo.codemc.org/repository/maven-public' }
|
maven { url 'https://repo.codemc.org/repository/maven-public' }
|
||||||
|
|
||||||
// Spigot API
|
// Spigot API
|
||||||
maven { url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' }
|
maven { url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' }
|
||||||
|
|
||||||
// PlaceholderAPI
|
// PlaceholderAPI
|
||||||
maven { url 'https://repo.extendedclip.com/content/repositories/placeholderapi/' }
|
maven { url 'https://repo.extendedclip.com/content/repositories/placeholderapi/' }
|
||||||
|
|
||||||
// ProtocolLib
|
// ProtocolLib
|
||||||
maven { url 'https://repo.dmulloy2.net/nexus/repository/public/' }
|
maven { url 'https://repo.dmulloy2.net/nexus/repository/public/' }
|
||||||
|
|
||||||
// WorldGuard
|
// WorldGuard
|
||||||
maven { url 'https://maven.enginehub.org/repo/' }
|
maven { url 'https://maven.enginehub.org/repo/' }
|
||||||
|
|
||||||
// FactionsUUID
|
// FactionsUUID
|
||||||
maven { url 'https://ci.ender.zone/plugin/repository/everything/' }
|
maven { url 'https://ci.ender.zone/plugin/repository/everything/' }
|
||||||
|
|
||||||
// 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) {
|
|
||||||
options.deprecation = true
|
|
||||||
options.encoding = 'UTF-8'
|
|
||||||
}
|
|
||||||
|
|
||||||
configurations.all {
|
|
||||||
exclude group: "org.codehaus.plexus", module: "plexus-utils"
|
|
||||||
exclude group: "com.mojang", module: "brigadier"
|
|
||||||
exclude group: "org.kitteh", module: "paste-gg-api"
|
|
||||||
exclude group: "org.spongepowered", module: "configurate-hocon"
|
|
||||||
exclude group: "com.darkblade12", module: "particleeffect"
|
|
||||||
}
|
|
||||||
|
|
||||||
shadowJar {
|
|
||||||
relocate('org.bstats.bukkit', 'com.willfp.eco.util.shaded.bstats')
|
|
||||||
relocate('org.apache.maven', 'com.willfp.eco.util.shaded.maven')
|
|
||||||
}
|
|
||||||
|
|
||||||
publishing {
|
|
||||||
publications {
|
|
||||||
shadow(MavenPublication) {
|
|
||||||
from components.java
|
|
||||||
artifact shadowJar
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.encoding = 'UTF-8'
|
||||||
|
}
|
||||||
|
|
||||||
|
configurations.all {
|
||||||
|
exclude group: "org.codehaus.plexus", module: "plexus-utils"
|
||||||
|
exclude group: "com.mojang", module: "brigadier"
|
||||||
|
exclude group: "org.kitteh", module: "paste-gg-api"
|
||||||
|
exclude group: "org.spongepowered", module: "configurate-hocon"
|
||||||
|
exclude group: "com.darkblade12", module: "particleeffect"
|
||||||
|
}
|
||||||
|
|
||||||
|
shadowJar {
|
||||||
|
relocate('org.bstats.bukkit', 'com.willfp.eco.util.shaded.bstats')
|
||||||
|
relocate('org.apache.maven', 'com.willfp.eco.util.shaded.maven')
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = '3.0.1'
|
version = findProperty("version")
|
||||||
java.sourceCompatibility = JavaVersion.VERSION_1_8
|
java.sourceCompatibility = JavaVersion.VERSION_1_8
|
||||||
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,46 @@
|
|||||||
|
package com.willfp.eco.proxy.v1_15_R1;
|
||||||
|
|
||||||
|
import com.willfp.eco.proxy.proxies.PacketPlayOutRecipeUpdateFixProxy;
|
||||||
|
import net.minecraft.server.v1_15_R1.IRecipe;
|
||||||
|
import net.minecraft.server.v1_15_R1.PacketPlayOutRecipeUpdate;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public final class PacketPlayOutRecipeUpdateFix implements PacketPlayOutRecipeUpdateFixProxy {
|
||||||
|
@Override
|
||||||
|
public List<Object> splitPackets(@NotNull final Object object,
|
||||||
|
@NotNull final Player player) {
|
||||||
|
if (!(object instanceof PacketPlayOutRecipeUpdate)) {
|
||||||
|
throw new IllegalArgumentException("Parameter not packet!");
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketPlayOutRecipeUpdate oldPacket = (PacketPlayOutRecipeUpdate) object;
|
||||||
|
List<IRecipe<?>> recipes = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
Field f = oldPacket.getClass().getDeclaredField("a");
|
||||||
|
f.setAccessible(true);
|
||||||
|
recipes.addAll((Collection<? extends IRecipe<?>>) f.get(oldPacket));
|
||||||
|
} catch (IllegalAccessException | NoSuchFieldException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Object> splitPackets = new ArrayList<>();
|
||||||
|
List<IRecipe<?>> splitRecipes = new ArrayList<>();
|
||||||
|
for (int i = 0; i < recipes.size(); i++) {
|
||||||
|
splitRecipes.add(recipes.get(i));
|
||||||
|
if (i % 100 == 0) {
|
||||||
|
PacketPlayOutRecipeUpdate newPacket = new PacketPlayOutRecipeUpdate(splitRecipes);
|
||||||
|
splitPackets.add(newPacket);
|
||||||
|
splitRecipes.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return splitPackets;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
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;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
|
||||||
|
public final class VillagerTrade implements VillagerTradeProxy {
|
||||||
|
@Override
|
||||||
|
public void displayTrade(@NotNull final MerchantRecipe merchantRecipe) {
|
||||||
|
try {
|
||||||
|
// Enables removing final modifier
|
||||||
|
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
||||||
|
modifiersField.setAccessible(true);
|
||||||
|
|
||||||
|
// Bukkit MerchantRecipe result
|
||||||
|
Field fResult = MerchantRecipe.class.getDeclaredField("result");
|
||||||
|
fResult.setAccessible(true);
|
||||||
|
|
||||||
|
ItemStack result = merchantRecipe.getResult();
|
||||||
|
Display.displayAndFinalize(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
|
||||||
|
modifiersField.setInt(fHandle, fHandle.getModifiers() & ~Modifier.FINAL); // Remove final
|
||||||
|
|
||||||
|
Field fSelling = net.minecraft.server.v1_15_R1.MerchantRecipe.class.getDeclaredField("sellingItem");
|
||||||
|
fSelling.setAccessible(true);
|
||||||
|
modifiersField.setInt(fSelling, fSelling.getModifiers() & ~Modifier.FINAL);
|
||||||
|
|
||||||
|
ItemStack selling = CraftItemStack.asBukkitCopy(handle.sellingItem);
|
||||||
|
Display.displayAndFinalize(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,46 @@
|
|||||||
|
package com.willfp.eco.proxy.v1_16_R1;
|
||||||
|
|
||||||
|
import com.willfp.eco.proxy.proxies.PacketPlayOutRecipeUpdateFixProxy;
|
||||||
|
import net.minecraft.server.v1_16_R1.IRecipe;
|
||||||
|
import net.minecraft.server.v1_16_R1.PacketPlayOutRecipeUpdate;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public final class PacketPlayOutRecipeUpdateFix implements PacketPlayOutRecipeUpdateFixProxy {
|
||||||
|
@Override
|
||||||
|
public List<Object> splitPackets(@NotNull final Object object,
|
||||||
|
@NotNull final Player player) {
|
||||||
|
if (!(object instanceof PacketPlayOutRecipeUpdate)) {
|
||||||
|
throw new IllegalArgumentException("Parameter not packet!");
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketPlayOutRecipeUpdate oldPacket = (PacketPlayOutRecipeUpdate) object;
|
||||||
|
List<IRecipe<?>> recipes = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
Field f = oldPacket.getClass().getDeclaredField("a");
|
||||||
|
f.setAccessible(true);
|
||||||
|
recipes.addAll((Collection<? extends IRecipe<?>>) f.get(oldPacket));
|
||||||
|
} catch (IllegalAccessException | NoSuchFieldException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Object> splitPackets = new ArrayList<>();
|
||||||
|
List<IRecipe<?>> splitRecipes = new ArrayList<>();
|
||||||
|
for (int i = 0; i < recipes.size(); i++) {
|
||||||
|
splitRecipes.add(recipes.get(i));
|
||||||
|
if (i % 100 == 0) {
|
||||||
|
PacketPlayOutRecipeUpdate newPacket = new PacketPlayOutRecipeUpdate(splitRecipes);
|
||||||
|
splitPackets.add(newPacket);
|
||||||
|
splitRecipes.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return splitPackets;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
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;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
|
||||||
|
public final class VillagerTrade implements VillagerTradeProxy {
|
||||||
|
@Override
|
||||||
|
public void displayTrade(@NotNull final MerchantRecipe merchantRecipe) {
|
||||||
|
try {
|
||||||
|
// Enables removing final modifier
|
||||||
|
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
||||||
|
modifiersField.setAccessible(true);
|
||||||
|
|
||||||
|
// Bukkit MerchantRecipe result
|
||||||
|
Field fResult = MerchantRecipe.class.getDeclaredField("result");
|
||||||
|
fResult.setAccessible(true);
|
||||||
|
ItemStack result = merchantRecipe.getResult();
|
||||||
|
Display.displayAndFinalize(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
|
||||||
|
modifiersField.setInt(fHandle, fHandle.getModifiers() & ~Modifier.FINAL); // Remove final
|
||||||
|
|
||||||
|
Field fSelling = net.minecraft.server.v1_16_R1.MerchantRecipe.class.getDeclaredField("sellingItem");
|
||||||
|
fSelling.setAccessible(true);
|
||||||
|
modifiersField.setInt(fSelling, fSelling.getModifiers() & ~Modifier.FINAL);
|
||||||
|
|
||||||
|
ItemStack selling = CraftItemStack.asBukkitCopy(handle.sellingItem);
|
||||||
|
Display.displayAndFinalize(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,46 @@
|
|||||||
|
package com.willfp.eco.proxy.v1_16_R2;
|
||||||
|
|
||||||
|
import com.willfp.eco.proxy.proxies.PacketPlayOutRecipeUpdateFixProxy;
|
||||||
|
import net.minecraft.server.v1_16_R2.IRecipe;
|
||||||
|
import net.minecraft.server.v1_16_R2.PacketPlayOutRecipeUpdate;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public final class PacketPlayOutRecipeUpdateFix implements PacketPlayOutRecipeUpdateFixProxy {
|
||||||
|
@Override
|
||||||
|
public List<Object> splitPackets(@NotNull final Object object,
|
||||||
|
@NotNull final Player player) {
|
||||||
|
if (!(object instanceof PacketPlayOutRecipeUpdate)) {
|
||||||
|
throw new IllegalArgumentException("Parameter not packet!");
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketPlayOutRecipeUpdate oldPacket = (PacketPlayOutRecipeUpdate) object;
|
||||||
|
List<IRecipe<?>> recipes = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
Field f = oldPacket.getClass().getDeclaredField("a");
|
||||||
|
f.setAccessible(true);
|
||||||
|
recipes.addAll((Collection<? extends IRecipe<?>>) f.get(oldPacket));
|
||||||
|
} catch (IllegalAccessException | NoSuchFieldException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Object> splitPackets = new ArrayList<>();
|
||||||
|
List<IRecipe<?>> splitRecipes = new ArrayList<>();
|
||||||
|
for (int i = 0; i < recipes.size(); i++) {
|
||||||
|
splitRecipes.add(recipes.get(i));
|
||||||
|
if (i % 100 == 0) {
|
||||||
|
PacketPlayOutRecipeUpdate newPacket = new PacketPlayOutRecipeUpdate(splitRecipes);
|
||||||
|
splitPackets.add(newPacket);
|
||||||
|
splitRecipes.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return splitPackets;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
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;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
|
||||||
|
public final class VillagerTrade implements VillagerTradeProxy {
|
||||||
|
@Override
|
||||||
|
public void displayTrade(@NotNull final MerchantRecipe merchantRecipe) {
|
||||||
|
try {
|
||||||
|
// Enables removing final modifier
|
||||||
|
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
||||||
|
modifiersField.setAccessible(true);
|
||||||
|
|
||||||
|
// Bukkit MerchantRecipe result
|
||||||
|
Field fResult = MerchantRecipe.class.getDeclaredField("result");
|
||||||
|
fResult.setAccessible(true);
|
||||||
|
ItemStack result = merchantRecipe.getResult();
|
||||||
|
Display.displayAndFinalize(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
|
||||||
|
modifiersField.setInt(fHandle, fHandle.getModifiers() & ~Modifier.FINAL); // Remove final
|
||||||
|
|
||||||
|
Field fSelling = net.minecraft.server.v1_16_R2.MerchantRecipe.class.getDeclaredField("sellingItem");
|
||||||
|
fSelling.setAccessible(true);
|
||||||
|
modifiersField.setInt(fSelling, fSelling.getModifiers() & ~Modifier.FINAL);
|
||||||
|
|
||||||
|
ItemStack selling = CraftItemStack.asBukkitCopy(handle.sellingItem);
|
||||||
|
Display.displayAndFinalize(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,46 @@
|
|||||||
|
package com.willfp.eco.proxy.v1_16_R3;
|
||||||
|
|
||||||
|
import com.willfp.eco.proxy.proxies.PacketPlayOutRecipeUpdateFixProxy;
|
||||||
|
import net.minecraft.server.v1_16_R3.IRecipe;
|
||||||
|
import net.minecraft.server.v1_16_R3.PacketPlayOutRecipeUpdate;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public final class PacketPlayOutRecipeUpdateFix implements PacketPlayOutRecipeUpdateFixProxy {
|
||||||
|
@Override
|
||||||
|
public List<Object> splitPackets(@NotNull final Object object,
|
||||||
|
@NotNull final Player player) {
|
||||||
|
if (!(object instanceof PacketPlayOutRecipeUpdate)) {
|
||||||
|
throw new IllegalArgumentException("Parameter not packet!");
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketPlayOutRecipeUpdate oldPacket = (PacketPlayOutRecipeUpdate) object;
|
||||||
|
List<IRecipe<?>> recipes = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
Field f = oldPacket.getClass().getDeclaredField("a");
|
||||||
|
f.setAccessible(true);
|
||||||
|
recipes.addAll((Collection<? extends IRecipe<?>>) f.get(oldPacket));
|
||||||
|
} catch (IllegalAccessException | NoSuchFieldException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Object> splitPackets = new ArrayList<>();
|
||||||
|
List<IRecipe<?>> splitRecipes = new ArrayList<>();
|
||||||
|
for (int i = 0; i < recipes.size(); i++) {
|
||||||
|
splitRecipes.add(recipes.get(i));
|
||||||
|
if (i % 100 == 0) {
|
||||||
|
PacketPlayOutRecipeUpdate newPacket = new PacketPlayOutRecipeUpdate(splitRecipes);
|
||||||
|
splitPackets.add(newPacket);
|
||||||
|
splitRecipes.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return splitPackets;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
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;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
|
||||||
|
public final class VillagerTrade implements VillagerTradeProxy {
|
||||||
|
@Override
|
||||||
|
public void displayTrade(@NotNull final MerchantRecipe merchantRecipe) {
|
||||||
|
try {
|
||||||
|
// Enables removing final modifier
|
||||||
|
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
||||||
|
modifiersField.setAccessible(true);
|
||||||
|
|
||||||
|
// Bukkit MerchantRecipe result
|
||||||
|
Field fResult = MerchantRecipe.class.getDeclaredField("result");
|
||||||
|
fResult.setAccessible(true);
|
||||||
|
ItemStack result = merchantRecipe.getResult();
|
||||||
|
Display.displayAndFinalize(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 Recipe
|
||||||
|
modifiersField.setInt(fHandle, fHandle.getModifiers() & ~Modifier.FINAL); // Remove final
|
||||||
|
|
||||||
|
Field fSelling = net.minecraft.server.v1_16_R3.MerchantRecipe.class.getDeclaredField("sellingItem");
|
||||||
|
fSelling.setAccessible(true);
|
||||||
|
modifiersField.setInt(fSelling, fSelling.getModifiers() & ~Modifier.FINAL);
|
||||||
|
|
||||||
|
ItemStack selling = CraftItemStack.asBukkitCopy(handle.sellingItem);
|
||||||
|
Display.displayAndFinalize(selling);
|
||||||
|
|
||||||
|
fSelling.set(handle, CraftItemStack.asNMSCopy(selling));
|
||||||
|
} catch (IllegalAccessException | NoSuchFieldException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
24
eco-core/core-plugin/build.gradle
Normal file
24
eco-core/core-plugin/build.gradle
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
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.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 fileTree(dir: '../../lib', include: ['*.jar'])
|
||||||
|
}
|
||||||
|
|
||||||
|
processResources {
|
||||||
|
filesNotMatching(["**/*.png", "**/models/**", "**/textures/**"]) {
|
||||||
|
expand projectVersion: project.version
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,128 @@
|
|||||||
|
package com.willfp.eco.spigot;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.ProtocolLibrary;
|
||||||
|
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.plugins.AnticheatAAC;
|
||||||
|
import com.willfp.eco.spigot.integrations.anticheat.plugins.AnticheatMatrix;
|
||||||
|
import com.willfp.eco.spigot.integrations.anticheat.plugins.AnticheatNCP;
|
||||||
|
import com.willfp.eco.spigot.integrations.antigrief.plugins.AntigriefFactionsUUID;
|
||||||
|
import com.willfp.eco.spigot.integrations.antigrief.plugins.AntigriefGriefPrevention;
|
||||||
|
import com.willfp.eco.spigot.integrations.antigrief.plugins.AntigriefKingdoms;
|
||||||
|
import com.willfp.eco.spigot.integrations.antigrief.plugins.AntigriefLands;
|
||||||
|
import com.willfp.eco.spigot.integrations.antigrief.plugins.AntigriefTowny;
|
||||||
|
import com.willfp.eco.spigot.integrations.antigrief.plugins.AntigriefWorldGuard;
|
||||||
|
import com.willfp.eco.util.command.AbstractCommand;
|
||||||
|
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.plugin.AbstractEcoPlugin;
|
||||||
|
import com.willfp.eco.util.protocollib.AbstractPacketAdapter;
|
||||||
|
import com.willfp.eco.util.recipe.RecipeListener;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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));
|
||||||
|
this.getEventManager().registerListener(new RecipeListener(this));
|
||||||
|
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketPlayOutRecipeUpdateFix(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()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@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<>();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.willfp.eco.spigot;
|
||||||
|
|
||||||
|
import com.willfp.eco.util.proxy.AbstractProxy;
|
||||||
|
import com.willfp.eco.proxy.util.ProxyFactory;
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
@UtilityClass
|
||||||
|
public class InternalProxyUtils {
|
||||||
|
/**
|
||||||
|
* Get the implementation of a specified proxy.
|
||||||
|
*
|
||||||
|
* @param proxyClass The proxy interface.
|
||||||
|
* @param <T> The type of the proxy.
|
||||||
|
* @return The proxy implementation.
|
||||||
|
*/
|
||||||
|
public @NotNull <T extends AbstractProxy> T getProxy(@NotNull final Class<T> proxyClass) {
|
||||||
|
return new ProxyFactory<>(EcoPlugin.getInstance(), proxyClass).getProxy();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package com.willfp.eco.spigot;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.PacketType;
|
||||||
|
import com.comphenix.protocol.ProtocolLibrary;
|
||||||
|
import com.comphenix.protocol.events.PacketAdapter;
|
||||||
|
import com.comphenix.protocol.events.PacketContainer;
|
||||||
|
import com.comphenix.protocol.events.PacketEvent;
|
||||||
|
import com.willfp.eco.proxy.proxies.PacketPlayOutRecipeUpdateFixProxy;
|
||||||
|
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class PacketPlayOutRecipeUpdateFix extends PacketAdapter {
|
||||||
|
/**
|
||||||
|
* Create new fixer for PacketPlayOutRecipeUpdate.
|
||||||
|
*
|
||||||
|
* @param plugin Plugin.
|
||||||
|
*/
|
||||||
|
public PacketPlayOutRecipeUpdateFix(@NotNull final AbstractEcoPlugin plugin) {
|
||||||
|
super(plugin, PacketType.Play.Server.RECIPE_UPDATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPacketSending(@NotNull final PacketEvent event) {
|
||||||
|
PacketContainer packet = event.getPacket();
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
|
||||||
|
List<Object> packets = InternalProxyUtils.getProxy(PacketPlayOutRecipeUpdateFixProxy.class).splitPackets(packet.getHandle(), player);
|
||||||
|
if (packets.size() > 1) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
for (Object o : packets) {
|
||||||
|
PacketContainer container = PacketContainer.fromPacket(o);
|
||||||
|
try {
|
||||||
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, container);
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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.plugins;
|
||||||
|
|
||||||
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.plugins;
|
||||||
|
|
||||||
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.plugins;
|
||||||
|
|
||||||
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.plugins;
|
||||||
|
|
||||||
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.plugins;
|
||||||
|
|
||||||
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.plugins;
|
||||||
|
|
||||||
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,4 +1,4 @@
|
|||||||
package com.willfp.eco.util.integrations.antigrief.plugins;
|
package com.willfp.eco.spigot.integrations.antigrief.plugins;
|
||||||
|
|
||||||
import com.willfp.eco.util.integrations.antigrief.AntigriefWrapper;
|
import com.willfp.eco.util.integrations.antigrief.AntigriefWrapper;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.willfp.eco.util.integrations.antigrief.plugins;
|
package com.willfp.eco.spigot.integrations.antigrief.plugins;
|
||||||
|
|
||||||
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.plugins;
|
||||||
|
|
||||||
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.plugins;
|
||||||
|
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
import com.sk89q.worldguard.LocalPlayer;
|
import com.sk89q.worldguard.LocalPlayer;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
name: eco
|
name: eco
|
||||||
version: 3.0.1
|
version: ${projectVersion}
|
||||||
main: com.willfp.eco.spigot.EcoSpigotMain
|
main: com.willfp.eco.spigot.EcoPlugin
|
||||||
api-version: 1.15
|
api-version: 1.15
|
||||||
authors: [Auxilor]
|
authors: [Auxilor]
|
||||||
website: willfp.com
|
website: willfp.com
|
||||||
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,20 @@
|
|||||||
|
package com.willfp.eco.proxy.proxies;
|
||||||
|
|
||||||
|
|
||||||
|
import com.willfp.eco.util.proxy.AbstractProxy;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface PacketPlayOutRecipeUpdateFixProxy extends AbstractProxy {
|
||||||
|
/**
|
||||||
|
* Split recipe update packet into smaller packets.
|
||||||
|
*
|
||||||
|
* @param object The packet.
|
||||||
|
* @param player The player.
|
||||||
|
* @return The packets, split up.
|
||||||
|
*/
|
||||||
|
List<Object> splitPackets(@NotNull Object object,
|
||||||
|
@NotNull Player player);
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
package com.willfp.eco.proxy.util;
|
||||||
|
|
||||||
|
import com.willfp.eco.util.internal.PluginDependent;
|
||||||
|
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 java.util.IdentityHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ProxyFactory<T extends AbstractProxy> extends PluginDependent {
|
||||||
|
/**
|
||||||
|
* Cached proxy implementations in order to not perform expensive reflective class-finding.
|
||||||
|
*/
|
||||||
|
private static final Map<Class<? extends AbstractProxy>, AbstractProxy> CACHE = new IdentityHashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class of the proxy interface.
|
||||||
|
*/
|
||||||
|
private final Class<T> proxyClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new Proxy Factory for a specific type.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin to create proxies for.
|
||||||
|
* @param proxyClass The class of the proxy interface.
|
||||||
|
*/
|
||||||
|
public ProxyFactory(@NotNull final AbstractEcoPlugin plugin,
|
||||||
|
@NotNull final Class<T> proxyClass) {
|
||||||
|
super(plugin);
|
||||||
|
this.proxyClass = proxyClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the implementation of a proxy.
|
||||||
|
*
|
||||||
|
* @return The proxy implementation.
|
||||||
|
*/
|
||||||
|
public @NotNull T getProxy() {
|
||||||
|
try {
|
||||||
|
T cachedProxy = attemptCache();
|
||||||
|
if (cachedProxy != null) {
|
||||||
|
return cachedProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
String className = this.getPlugin().getProxyPackage() + "." + ProxyConstants.NMS_VERSION + "." + proxyClass.getSimpleName().replace("Proxy", "");
|
||||||
|
final Class<?> class2 = Class.forName(className);
|
||||||
|
Object instance = class2.getConstructor().newInstance();
|
||||||
|
if (proxyClass.isAssignableFrom(class2) && proxyClass.isInstance(instance)) {
|
||||||
|
T proxy = proxyClass.cast(instance);
|
||||||
|
CACHE.put(proxyClass, proxy);
|
||||||
|
return proxy;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// If not returned, then throw error
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new UnsupportedVersionException("You're running an unsupported server version: " + ProxyConstants.NMS_VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
private T attemptCache() {
|
||||||
|
Object proxy = CACHE.get(proxyClass);
|
||||||
|
if (proxy == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (proxyClass.isInstance(proxy)) {
|
||||||
|
return proxyClass.cast(proxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
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'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,163 @@
|
|||||||
|
package com.willfp.eco.util.config;
|
||||||
|
|
||||||
|
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.file.YamlConfiguration;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public abstract class StaticBaseConfig extends PluginDependent implements ValueGetter {
|
||||||
|
/**
|
||||||
|
* The linked {@link YamlConfiguration} where values are physically stored.
|
||||||
|
*/
|
||||||
|
@Getter(AccessLevel.PUBLIC)
|
||||||
|
private 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).
|
||||||
|
*/
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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(plugin);
|
||||||
|
this.name = configName + ".yml";
|
||||||
|
|
||||||
|
if (!new File(this.getPlugin().getDataFolder(), this.name).exists()) {
|
||||||
|
createFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.configFile = new File(this.getPlugin().getDataFolder(), this.name);
|
||||||
|
this.config = YamlConfiguration.loadConfiguration(configFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createFile() {
|
||||||
|
this.getPlugin().saveResource(name, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an integer from config.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The found value, or 0 if not found.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getInt(@NotNull final String path) {
|
||||||
|
return config.getInt(path, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public List<Integer> getInts(@NotNull final String path) {
|
||||||
|
return config.getIntegerList(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a boolean from config.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The found value, or false if not found.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean getBool(@NotNull final String path) {
|
||||||
|
return config.getBoolean(path, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public List<Boolean> getBools(@NotNull final String path) {
|
||||||
|
return config.getBooleanList(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public String getString(@NotNull final String path) {
|
||||||
|
return StringUtils.translate(Objects.requireNonNull(config.getString(path, "")));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public List<String> getStrings(@NotNull final String path) {
|
||||||
|
return config.getStringList(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a decimal from config.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The found value, or 0 if not found.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public double getDouble(@NotNull final String path) {
|
||||||
|
return config.getDouble(path, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public List<Double> getDoubles(@NotNull final String path) {
|
||||||
|
return config.getDoubleList(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
159
eco-util/src/main/java/com/willfp/eco/util/display/Display.java
Normal file
159
eco-util/src/main/java/com/willfp/eco/util/display/Display.java
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
package com.willfp.eco.util.display;
|
||||||
|
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
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<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registered finalize functions.
|
||||||
|
*/
|
||||||
|
public static final List<Function<ItemStack, ItemStack>> FINALIZE_FUNCTIONS = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registered finalize test functions.
|
||||||
|
*/
|
||||||
|
public static final List<Predicate<ItemStack>> FINALIZE_TEST_FUNCTIONS = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register finalize function.
|
||||||
|
*
|
||||||
|
* @param function The function.
|
||||||
|
*/
|
||||||
|
public void registerFinalizeModule(@NotNull final Function<ItemStack, ItemStack> function) {
|
||||||
|
FINALIZE_FUNCTIONS.add(function);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register finalize test function.
|
||||||
|
*
|
||||||
|
* @param function The function.
|
||||||
|
*/
|
||||||
|
public void registerFinalizeTestModule(@NotNull final Predicate<ItemStack> function) {
|
||||||
|
FINALIZE_TEST_FUNCTIONS.add(function);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display on ItemStacks.
|
||||||
|
*
|
||||||
|
* @param itemStack The item.
|
||||||
|
*/
|
||||||
|
public ItemStack display(@NotNull final ItemStack 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.
|
||||||
|
*/
|
||||||
|
public ItemStack displayAndFinalize(@NotNull final ItemStack itemStack) {
|
||||||
|
return finalize(display(itemStack));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Revert on ItemStacks.
|
||||||
|
*
|
||||||
|
* @param itemStack The item.
|
||||||
|
*/
|
||||||
|
public ItemStack revert(@NotNull final ItemStack itemStack) {
|
||||||
|
for (Function<ItemStack, ItemStack> displayFunction : REVERT_FUNCTIONS) {
|
||||||
|
displayFunction.apply(itemStack);
|
||||||
|
}
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finalize an ItemStacks.
|
||||||
|
*
|
||||||
|
* @param itemStack The item.
|
||||||
|
*/
|
||||||
|
public ItemStack finalize(@NotNull final ItemStack itemStack) {
|
||||||
|
for (Function<ItemStack, ItemStack> function : FINALIZE_FUNCTIONS) {
|
||||||
|
function.apply(itemStack);
|
||||||
|
}
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finalize an ItemStacks.
|
||||||
|
*
|
||||||
|
* @param itemStack The item.
|
||||||
|
*/
|
||||||
|
public boolean isFinalized(@NotNull final ItemStack itemStack) {
|
||||||
|
for (Predicate<ItemStack> function : FINALIZE_TEST_FUNCTIONS) {
|
||||||
|
if (function.test(itemStack)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
@@ -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