Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
183b18c0ec | ||
|
|
e026a767d9 | ||
|
|
d2966aa428 | ||
|
|
9168e68b5a | ||
|
|
51a61b65c6 | ||
|
|
76be236dac | ||
|
|
f1bbac2dd0 | ||
|
|
6e88aef572 | ||
|
|
804f187964 | ||
|
|
623b8a18f4 | ||
|
|
0d4e424582 | ||
|
|
452e499467 | ||
|
|
b2950ab035 | ||
|
|
e47d05ccb2 | ||
|
|
b9e61b8c0d | ||
|
|
0f35d5d16e | ||
|
|
3a7315d728 | ||
|
|
6f193f70b0 | ||
|
|
bab3f078f6 | ||
|
|
5b4b17b97f | ||
|
|
f0e02ca25e | ||
|
|
7426e9adba |
@@ -12,7 +12,7 @@ dependencies {
|
|||||||
implementation(project(":eco-core:core-backend"))
|
implementation(project(":eco-core:core-backend"))
|
||||||
implementation(project(":eco-core:core-nms:v1_16_R3"))
|
implementation(project(":eco-core:core-nms:v1_16_R3"))
|
||||||
implementation(project(path = ":eco-core:core-nms:v1_17_R1", configuration = "reobf"))
|
implementation(project(path = ":eco-core:core-nms:v1_17_R1", configuration = "reobf"))
|
||||||
implementation(project(":eco-core:core-nms:v1_18_R1"))
|
implementation(project(path = ":eco-core:core-nms:v1_18_R1", configuration = "reobf"))
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
|
|||||||
@@ -28,6 +28,9 @@ import java.lang.annotation.Target;
|
|||||||
* }
|
* }
|
||||||
* }</pre>
|
* }</pre>
|
||||||
* <p>
|
* <p>
|
||||||
|
* If using kotlin, you have to annotate the method with {@code @JvmStatic}
|
||||||
|
* in order to prevent null pointer exceptions.
|
||||||
|
* <p>
|
||||||
* Config update methods in all classes in a plugin jar will be called
|
* Config update methods in all classes in a plugin jar will be called
|
||||||
* on reload.
|
* on reload.
|
||||||
* <p>
|
* <p>
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ public class CustomItem implements TestableItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemStack getItem() {
|
public ItemStack getItem() {
|
||||||
return item;
|
return item.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public class EnchantedBookBuilder extends AbstractItemStackBuilder<EnchantmentSt
|
|||||||
* @return The builder.
|
* @return The builder.
|
||||||
*/
|
*/
|
||||||
public EnchantedBookBuilder addStoredEnchantment(@NotNull final Supplier<Enchantment> enchantment,
|
public EnchantedBookBuilder addStoredEnchantment(@NotNull final Supplier<Enchantment> enchantment,
|
||||||
final Supplier<Integer> level) {
|
@NotNull final Supplier<Integer> level) {
|
||||||
return this.addStoredEnchantment(enchantment.get(), level.get());
|
return this.addStoredEnchantment(enchantment.get(), level.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ public class Paste {
|
|||||||
conn.setRequestMethod("GET");
|
conn.setRequestMethod("GET");
|
||||||
try (var reader = new BufferedReader(
|
try (var reader = new BufferedReader(
|
||||||
new InputStreamReader(conn.getInputStream()))) {
|
new InputStreamReader(conn.getInputStream()))) {
|
||||||
for (String line; (line = reader.readLine()) != null; ) {
|
for (String line; (line = reader.readLine()) != null;) {
|
||||||
result.append(line);
|
result.append(line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,6 +91,24 @@ public final class ListUtils {
|
|||||||
return index >= 0 && index < list.size() ? list.get(index) : null;
|
return index >= 0 && index < list.size() ? list.get(index) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if an iterable of strings contains a certain element regardless of case.
|
||||||
|
*
|
||||||
|
* @param list The list.
|
||||||
|
* @param element The element.
|
||||||
|
* @return If contained.
|
||||||
|
*/
|
||||||
|
public static boolean containsIgnoreCase(@NotNull final Iterable<String> list,
|
||||||
|
@NotNull final String element) {
|
||||||
|
for (String s : list) {
|
||||||
|
if (s.equalsIgnoreCase(element)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private ListUtils() {
|
private ListUtils() {
|
||||||
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -185,11 +185,23 @@ public final class NumberUtils {
|
|||||||
/**
|
/**
|
||||||
* Get Log base 2 of a number.
|
* Get Log base 2 of a number.
|
||||||
*
|
*
|
||||||
* @param toLog The number.
|
* @param a The number.
|
||||||
* @return The result.
|
* @return The result.
|
||||||
*/
|
*/
|
||||||
public static int log2(final int toLog) {
|
public static int log2(final int a) {
|
||||||
return (int) (Math.log(toLog) / Math.log(2));
|
return (int) logBase(a, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log with a base.
|
||||||
|
*
|
||||||
|
* @param a The number.
|
||||||
|
* @param base The base.
|
||||||
|
* @return The logarithm.
|
||||||
|
*/
|
||||||
|
public static double logBase(final double a,
|
||||||
|
final double base) {
|
||||||
|
return Math.log(a) / Math.log(base);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.willfp.eco.util;
|
|||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.gson.JsonSyntaxException;
|
||||||
import com.willfp.eco.core.Prerequisite;
|
import com.willfp.eco.core.Prerequisite;
|
||||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager;
|
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
@@ -58,6 +59,13 @@ public final class StringUtils {
|
|||||||
.hexColors()
|
.hexColors()
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GSON serializer.
|
||||||
|
*/
|
||||||
|
private static final GsonComponentSerializer GSON_COMPONENT_SERIALIZER = GsonComponentSerializer.builder()
|
||||||
|
.emitLegacyHoverEvent()
|
||||||
|
.build();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Color map.
|
* Color map.
|
||||||
*/
|
*/
|
||||||
@@ -415,7 +423,7 @@ public final class StringUtils {
|
|||||||
if (legacy == null) {
|
if (legacy == null) {
|
||||||
processed = "";
|
processed = "";
|
||||||
}
|
}
|
||||||
return GsonComponentSerializer.gson().serialize(
|
return GSON_COMPONENT_SERIALIZER.serialize(
|
||||||
Component.empty().decoration(TextDecoration.ITALIC, false).append(
|
Component.empty().decoration(TextDecoration.ITALIC, false).append(
|
||||||
LEGACY_COMPONENT_SERIALIZER.deserialize(processed)
|
LEGACY_COMPONENT_SERIALIZER.deserialize(processed)
|
||||||
)
|
)
|
||||||
@@ -429,10 +437,17 @@ public final class StringUtils {
|
|||||||
* @return The legacy string.
|
* @return The legacy string.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public static String jsonToLegacy(@NotNull final String json) {
|
public static String jsonToLegacy(@Nullable final String json) {
|
||||||
return LEGACY_COMPONENT_SERIALIZER.serialize(
|
if (json == null || json.isEmpty()) {
|
||||||
GsonComponentSerializer.gson().deserialize(json)
|
return "";
|
||||||
);
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Component component = GSON_COMPONENT_SERIALIZER.deserialize(json);
|
||||||
|
return LEGACY_COMPONENT_SERIALIZER.serialize(component);
|
||||||
|
} catch (JsonSyntaxException e) {
|
||||||
|
return json;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("io.papermc.paperweight.userdev") version "1.2.0"
|
id("io.papermc.paperweight.userdev") version "1.3.3"
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "com.willfp"
|
group = "com.willfp"
|
||||||
|
|||||||
@@ -87,33 +87,29 @@ class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemS
|
|||||||
|
|
||||||
override fun getLore(): List<String> {
|
override fun getLore(): List<String> {
|
||||||
if (loreCache != null) {
|
if (loreCache != null) {
|
||||||
return loreCache as List<String>
|
return loreCache!!
|
||||||
}
|
|
||||||
|
|
||||||
val lore: MutableList<String> = ArrayList()
|
|
||||||
|
|
||||||
for (s in getLoreJSON()) {
|
|
||||||
lore.add(StringUtils.jsonToLegacy(s))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val lore = this.getLoreJSON().map { StringUtils.jsonToLegacy(it) }
|
||||||
loreCache = lore
|
loreCache = lore
|
||||||
return lore
|
return lore
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getLoreJSON(): List<String> {
|
private fun getLoreJSON(): List<String> {
|
||||||
val displayTag = handle.getTagElement("display") ?: return emptyList()
|
val displayTag = handle.getTagElement("display") ?: return emptyList()
|
||||||
return if (displayTag.contains("Lore")) {
|
|
||||||
val loreTag = displayTag.getList("Lore", CraftMagicNumbers.NBT.TAG_STRING)
|
|
||||||
val lore: MutableList<String> = ArrayList(loreTag.size)
|
|
||||||
|
|
||||||
for (i in loreTag.indices) {
|
if (!displayTag.contains("Lore")) {
|
||||||
lore.add(loreTag.getString(i))
|
return emptyList()
|
||||||
}
|
|
||||||
|
|
||||||
lore
|
|
||||||
} else {
|
|
||||||
emptyList()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val loreTag = displayTag.getList("Lore", CraftMagicNumbers.NBT.TAG_STRING)
|
||||||
|
val lore = mutableListOf<String>()
|
||||||
|
|
||||||
|
for (i in loreTag.indices) {
|
||||||
|
lore.add(loreTag.getString(i))
|
||||||
|
}
|
||||||
|
|
||||||
|
return lore
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addItemFlags(vararg hideFlags: ItemFlag) {
|
override fun addItemFlags(vararg hideFlags: ItemFlag) {
|
||||||
@@ -155,11 +151,11 @@ class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemS
|
|||||||
|
|
||||||
private var flagBits: Int
|
private var flagBits: Int
|
||||||
get() =
|
get() =
|
||||||
if (handle.hasTag() && handle.tag!!.contains(
|
if (handle.hasTag() && handle.tag.contains(
|
||||||
"HideFlags",
|
"HideFlags",
|
||||||
99
|
99
|
||||||
)
|
)
|
||||||
) handle.tag!!.getInt("HideFlags") else 0
|
) handle.tag.getInt("HideFlags") else 0
|
||||||
set(value) =
|
set(value) =
|
||||||
handle.orCreateTag.putInt("HideFlags", value)
|
handle.orCreateTag.putInt("HideFlags", value)
|
||||||
|
|
||||||
@@ -188,4 +184,4 @@ class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemS
|
|||||||
bukkit.itemMeta = CraftItemStack.asCraftMirror(handle).itemMeta
|
bukkit.itemMeta = CraftItemStack.asCraftMirror(handle).itemMeta
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,16 @@
|
|||||||
|
plugins {
|
||||||
|
id("io.papermc.paperweight.userdev") version "1.3.3"
|
||||||
|
}
|
||||||
|
|
||||||
group = "com.willfp"
|
group = "com.willfp"
|
||||||
version = rootProject.version
|
version = rootProject.version
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(files("./impl.jar"))
|
paperDevBundle("1.18.1-R0.1-SNAPSHOT")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
build {
|
||||||
|
dependsOn(reobfJar)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Binary file not shown.
@@ -0,0 +1,15 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_18_R1
|
||||||
|
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.AutoCraftProxy
|
||||||
|
import net.minecraft.network.protocol.game.ClientboundPlaceGhostRecipePacket
|
||||||
|
import net.minecraft.resources.ResourceLocation
|
||||||
|
|
||||||
|
class AutoCraft : AutoCraftProxy {
|
||||||
|
override fun modifyPacket(packet: Any) {
|
||||||
|
val recipePacket = packet as ClientboundPlaceGhostRecipePacket
|
||||||
|
val fKey = recipePacket.javaClass.getDeclaredField("b")
|
||||||
|
fKey.isAccessible = true
|
||||||
|
val key = fKey[recipePacket] as ResourceLocation
|
||||||
|
fKey[recipePacket] = ResourceLocation(key.namespace, key.path + "_displayed")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_18_R1
|
||||||
|
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.BlockBreakProxy
|
||||||
|
import org.bukkit.block.Block
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
|
class BlockBreak : BlockBreakProxy {
|
||||||
|
override fun breakBlock(
|
||||||
|
player: Player,
|
||||||
|
block: Block
|
||||||
|
) {
|
||||||
|
player.breakBlock(block)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_18_R1
|
||||||
|
|
||||||
|
import com.willfp.eco.core.display.Display
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.ChatComponentProxy
|
||||||
|
import net.kyori.adventure.nbt.api.BinaryTagHolder
|
||||||
|
import net.kyori.adventure.text.BuildableComponent
|
||||||
|
import net.kyori.adventure.text.Component
|
||||||
|
import net.kyori.adventure.text.TranslatableComponent
|
||||||
|
import net.kyori.adventure.text.event.HoverEvent
|
||||||
|
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer
|
||||||
|
import net.minecraft.nbt.TagParser
|
||||||
|
import org.bukkit.Material
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.inventory.CraftItemStack
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
class ChatComponent : ChatComponentProxy {
|
||||||
|
private val gsonComponentSerializer = GsonComponentSerializer.gson()
|
||||||
|
|
||||||
|
override fun modifyComponent(obj: Any, player: Player): Any {
|
||||||
|
if (obj !is net.minecraft.network.chat.Component) {
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
|
||||||
|
val component = gsonComponentSerializer.deserialize(
|
||||||
|
net.minecraft.network.chat.Component.Serializer.toJson(
|
||||||
|
obj
|
||||||
|
)
|
||||||
|
).asComponent() as BuildableComponent<*, *>
|
||||||
|
|
||||||
|
val newComponent = modifyBaseComponent(component, player)
|
||||||
|
|
||||||
|
return net.minecraft.network.chat.Component.Serializer.fromJson(
|
||||||
|
gsonComponentSerializer.serialize(newComponent.asComponent())
|
||||||
|
) ?: obj
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun modifyBaseComponent(baseComponent: Component, player: Player): Component {
|
||||||
|
var component = baseComponent
|
||||||
|
|
||||||
|
if (component is TranslatableComponent) {
|
||||||
|
val args = mutableListOf<Component>()
|
||||||
|
for (arg in component.args()) {
|
||||||
|
args.add(modifyBaseComponent(arg, player))
|
||||||
|
}
|
||||||
|
component = component.args(args)
|
||||||
|
}
|
||||||
|
|
||||||
|
val children = mutableListOf<Component>()
|
||||||
|
for (child in component.children()) {
|
||||||
|
children.add(modifyBaseComponent(child, player))
|
||||||
|
}
|
||||||
|
component = component.children(children)
|
||||||
|
|
||||||
|
val hoverEvent: HoverEvent<Any> = component.style().hoverEvent() as HoverEvent<Any>? ?: return component
|
||||||
|
|
||||||
|
val showItem = hoverEvent.value()
|
||||||
|
|
||||||
|
if (showItem !is HoverEvent.ShowItem) {
|
||||||
|
return component
|
||||||
|
}
|
||||||
|
|
||||||
|
val newShowItem = showItem.nbt(
|
||||||
|
BinaryTagHolder.of(
|
||||||
|
CraftItemStack.asNMSCopy(
|
||||||
|
Display.display(
|
||||||
|
CraftItemStack.asBukkitCopy(
|
||||||
|
CraftItemStack.asNMSCopy(
|
||||||
|
ItemStack(
|
||||||
|
Material.matchMaterial(
|
||||||
|
showItem.item()
|
||||||
|
.toString()
|
||||||
|
) ?: return component,
|
||||||
|
showItem.count()
|
||||||
|
)
|
||||||
|
).apply {
|
||||||
|
this.tag = TagParser.parseTag(
|
||||||
|
showItem.nbt()?.string() ?: return component
|
||||||
|
) ?: return component
|
||||||
|
}
|
||||||
|
),
|
||||||
|
player
|
||||||
|
)
|
||||||
|
).orCreateTag.toString()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
val newHover = hoverEvent.value(newShowItem)
|
||||||
|
val style = component.style().hoverEvent(newHover)
|
||||||
|
return component.style(style)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_18_R1
|
||||||
|
|
||||||
|
import com.willfp.eco.core.fast.FastItemStack
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.v1_18_R1.fast.NMSFastItemStack
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
|
||||||
|
class FastItemStackFactory : FastItemStackFactoryProxy {
|
||||||
|
override fun create(itemStack: ItemStack): FastItemStack {
|
||||||
|
return NMSFastItemStack(itemStack)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_18_R1
|
||||||
|
|
||||||
|
import com.mojang.authlib.GameProfile
|
||||||
|
import com.mojang.authlib.properties.Property
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.SkullProxy
|
||||||
|
import org.bukkit.inventory.meta.SkullMeta
|
||||||
|
import java.lang.reflect.Field
|
||||||
|
import java.lang.reflect.Method
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
|
class Skull : SkullProxy {
|
||||||
|
private lateinit var setProfile: Method
|
||||||
|
private lateinit var profile: Field
|
||||||
|
|
||||||
|
override fun setSkullTexture(
|
||||||
|
meta: SkullMeta,
|
||||||
|
base64: String
|
||||||
|
) {
|
||||||
|
if (!this::setProfile.isInitialized) {
|
||||||
|
setProfile = meta.javaClass.getDeclaredMethod("setProfile", GameProfile::class.java)
|
||||||
|
setProfile.isAccessible = true
|
||||||
|
}
|
||||||
|
val uuid = UUID(
|
||||||
|
base64.substring(base64.length - 20).hashCode().toLong(),
|
||||||
|
base64.substring(base64.length - 10).hashCode().toLong()
|
||||||
|
)
|
||||||
|
val profile = GameProfile(uuid, "eco")
|
||||||
|
profile.properties.put("textures", Property("textures", base64))
|
||||||
|
setProfile.invoke(meta, profile)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getSkullTexture(
|
||||||
|
meta: SkullMeta
|
||||||
|
): String? {
|
||||||
|
if (!this::profile.isInitialized) {
|
||||||
|
profile = meta.javaClass.getDeclaredField("profile")
|
||||||
|
profile.isAccessible = true
|
||||||
|
}
|
||||||
|
val profile = profile[meta] as GameProfile? ?: return null
|
||||||
|
val properties = profile.properties ?: return null
|
||||||
|
val prop = properties["textures"] ?: return null
|
||||||
|
return prop.toMutableList().firstOrNull()?.name
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_18_R1
|
||||||
|
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.TPSProxy
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.CraftServer
|
||||||
|
|
||||||
|
class TPS : TPSProxy {
|
||||||
|
override fun getTPS(): Double {
|
||||||
|
return (Bukkit.getServer() as CraftServer).handle.server.recentTps[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_18_R1
|
||||||
|
|
||||||
|
import com.willfp.eco.core.display.Display
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.VillagerTradeProxy
|
||||||
|
import net.minecraft.world.item.trading.MerchantOffer
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.inventory.CraftMerchantRecipe
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.inventory.MerchantRecipe
|
||||||
|
import java.lang.reflect.Field
|
||||||
|
|
||||||
|
class VillagerTrade : VillagerTradeProxy {
|
||||||
|
private val handle: Field = CraftMerchantRecipe::class.java.getDeclaredField("handle")
|
||||||
|
|
||||||
|
override fun displayTrade(
|
||||||
|
recipe: MerchantRecipe,
|
||||||
|
player: Player
|
||||||
|
): MerchantRecipe {
|
||||||
|
val oldRecipe = recipe as CraftMerchantRecipe
|
||||||
|
val newRecipe = CraftMerchantRecipe(
|
||||||
|
Display.display(recipe.getResult().clone(), player),
|
||||||
|
recipe.getUses(),
|
||||||
|
recipe.getMaxUses(),
|
||||||
|
recipe.hasExperienceReward(),
|
||||||
|
recipe.getVillagerExperience(),
|
||||||
|
recipe.getPriceMultiplier()
|
||||||
|
)
|
||||||
|
for (ingredient in recipe.getIngredients()) {
|
||||||
|
newRecipe.addIngredient(Display.display(ingredient.clone(), player))
|
||||||
|
}
|
||||||
|
getHandle(newRecipe).setSpecialPriceDiff(getHandle(oldRecipe).getSpecialPriceDiff())
|
||||||
|
return newRecipe
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getHandle(recipe: CraftMerchantRecipe): MerchantOffer {
|
||||||
|
return handle[recipe] as MerchantOffer
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
handle.isAccessible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_18_R1.fast
|
||||||
|
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.inventory.CraftItemStack
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
import java.lang.reflect.Field
|
||||||
|
|
||||||
|
private val field: Field = CraftItemStack::class.java.getDeclaredField("handle").apply {
|
||||||
|
isAccessible = true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ItemStack.getNMSStack(): net.minecraft.world.item.ItemStack {
|
||||||
|
return if (this !is CraftItemStack) {
|
||||||
|
CraftItemStack.asNMSCopy(this)
|
||||||
|
} else {
|
||||||
|
field[this] as net.minecraft.world.item.ItemStack? ?: CraftItemStack.asNMSCopy(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,188 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_18_R1.fast
|
||||||
|
|
||||||
|
import com.willfp.eco.internal.fast.EcoFastItemStack
|
||||||
|
import com.willfp.eco.util.StringUtils
|
||||||
|
import net.minecraft.nbt.CompoundTag
|
||||||
|
import net.minecraft.nbt.ListTag
|
||||||
|
import net.minecraft.nbt.StringTag
|
||||||
|
import net.minecraft.world.item.EnchantedBookItem
|
||||||
|
import net.minecraft.world.item.Item
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
|
import net.minecraft.world.item.Items
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.inventory.CraftItemStack
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.util.CraftMagicNumbers
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.util.CraftNamespacedKey
|
||||||
|
import org.bukkit.enchantments.Enchantment
|
||||||
|
import org.bukkit.inventory.ItemFlag
|
||||||
|
import kotlin.experimental.and
|
||||||
|
|
||||||
|
@Suppress("UsePropertyAccessSyntax")
|
||||||
|
class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemStack<ItemStack>(
|
||||||
|
itemStack.getNMSStack(), itemStack
|
||||||
|
) {
|
||||||
|
private var loreCache: List<String>? = null
|
||||||
|
|
||||||
|
override fun getEnchantmentsOnItem(checkStored: Boolean): Map<Enchantment, Int> {
|
||||||
|
val enchantmentNBT =
|
||||||
|
if (checkStored && handle.item === Items.ENCHANTED_BOOK) EnchantedBookItem.getEnchantments(
|
||||||
|
handle
|
||||||
|
) else handle.enchantmentTags
|
||||||
|
val foundEnchantments: MutableMap<Enchantment, Int> = HashMap()
|
||||||
|
for (base in enchantmentNBT) {
|
||||||
|
val compound = base as CompoundTag
|
||||||
|
val key = compound.getString("id")
|
||||||
|
val level = ('\uffff'.code.toShort() and compound.getShort("lvl")).toInt()
|
||||||
|
val found = Enchantment.getByKey(CraftNamespacedKey.fromStringOrNull(key))
|
||||||
|
if (found != null) {
|
||||||
|
foundEnchantments[found] = level
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return foundEnchantments
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getLevelOnItem(
|
||||||
|
enchantment: Enchantment,
|
||||||
|
checkStored: Boolean
|
||||||
|
): Int {
|
||||||
|
val enchantmentNBT =
|
||||||
|
if (checkStored && handle.item === Items.ENCHANTED_BOOK) EnchantedBookItem.getEnchantments(
|
||||||
|
handle
|
||||||
|
) else handle.enchantmentTags
|
||||||
|
for (base in enchantmentNBT) {
|
||||||
|
val compound = base as CompoundTag
|
||||||
|
val key = compound.getString("id")
|
||||||
|
if (key != enchantment.key.toString()) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return ('\uffff'.code.toShort() and compound.getShort("lvl")).toInt()
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setLore(lore: List<String>?) {
|
||||||
|
loreCache = null
|
||||||
|
val jsonLore: MutableList<String> = ArrayList()
|
||||||
|
|
||||||
|
if (lore != null) {
|
||||||
|
for (s in lore) {
|
||||||
|
jsonLore.add(StringUtils.legacyToJson(s))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val displayTag = handle.getOrCreateTagElement("display")
|
||||||
|
|
||||||
|
if (!displayTag.contains("Lore")) {
|
||||||
|
displayTag.put("Lore", ListTag())
|
||||||
|
}
|
||||||
|
|
||||||
|
val loreTag = displayTag.getList("Lore", CraftMagicNumbers.NBT.TAG_STRING)
|
||||||
|
|
||||||
|
loreTag.clear()
|
||||||
|
|
||||||
|
for (s in jsonLore) {
|
||||||
|
loreTag.add(StringTag.valueOf(s))
|
||||||
|
}
|
||||||
|
|
||||||
|
apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getLore(): List<String> {
|
||||||
|
if (loreCache != null) {
|
||||||
|
return loreCache!!
|
||||||
|
}
|
||||||
|
|
||||||
|
val lore = this.getLoreJSON().map { StringUtils.jsonToLegacy(it) }
|
||||||
|
loreCache = lore
|
||||||
|
return lore
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getLoreJSON(): List<String> {
|
||||||
|
val displayTag = handle.getTagElement("display") ?: return emptyList()
|
||||||
|
|
||||||
|
if (!displayTag.contains("Lore")) {
|
||||||
|
return emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
val loreTag = displayTag.getList("Lore", CraftMagicNumbers.NBT.TAG_STRING)
|
||||||
|
val lore = ArrayList<String>(loreTag.size)
|
||||||
|
|
||||||
|
for (i in loreTag.indices) {
|
||||||
|
lore.add(loreTag.getString(i))
|
||||||
|
}
|
||||||
|
|
||||||
|
return lore
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addItemFlags(vararg hideFlags: ItemFlag) {
|
||||||
|
for (flag in hideFlags) {
|
||||||
|
this.flagBits = this.flagBits or getBitModifier(flag)
|
||||||
|
}
|
||||||
|
|
||||||
|
apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun removeItemFlags(vararg hideFlags: ItemFlag) {
|
||||||
|
for (flag in hideFlags) {
|
||||||
|
this.flagBits = this.flagBits and getBitModifier(flag)
|
||||||
|
}
|
||||||
|
|
||||||
|
apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemFlags(): MutableSet<ItemFlag> {
|
||||||
|
val flags = mutableSetOf<ItemFlag>()
|
||||||
|
|
||||||
|
var flagArr: Array<ItemFlag>
|
||||||
|
val size = ItemFlag.values().also { flagArr = it }.size
|
||||||
|
|
||||||
|
for (i in 0 until size) {
|
||||||
|
val flag = flagArr[i]
|
||||||
|
if (this.hasItemFlag(flag)) {
|
||||||
|
flags.add(flag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return flags
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hasItemFlag(flag: ItemFlag): Boolean {
|
||||||
|
val bitModifier = getBitModifier(flag)
|
||||||
|
return this.flagBits and bitModifier == bitModifier
|
||||||
|
}
|
||||||
|
|
||||||
|
private var flagBits: Int
|
||||||
|
get() =
|
||||||
|
if (handle.hasTag() && handle.tag!!.contains(
|
||||||
|
"HideFlags",
|
||||||
|
99
|
||||||
|
)
|
||||||
|
) handle.tag!!.getInt("HideFlags") else 0
|
||||||
|
set(value) =
|
||||||
|
handle.orCreateTag.putInt("HideFlags", value)
|
||||||
|
|
||||||
|
override fun getRepairCost(): Int {
|
||||||
|
return handle.baseRepairCost
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setRepairCost(cost: Int) {
|
||||||
|
handle.setRepairCost(cost)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (other !is NMSFastItemStack) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return other.hashCode() == this.hashCode()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
return handle.tag?.hashCode() ?: (0b00010101 * 31 + Item.getId(handle.getItem()))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun apply() {
|
||||||
|
if (bukkit !is CraftItemStack) {
|
||||||
|
bukkit.itemMeta = CraftItemStack.asCraftMirror(handle).itemMeta
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,7 +16,9 @@ dependencies {
|
|||||||
compileOnly 'com.github.TechFortress:GriefPrevention:16.17.1'
|
compileOnly 'com.github.TechFortress:GriefPrevention:16.17.1'
|
||||||
compileOnly 'com.massivecraft:Factions:1.6.9.5-U0.5.10'
|
compileOnly 'com.massivecraft:Factions:1.6.9.5-U0.5.10'
|
||||||
compileOnly 'com.github.cryptomorin:kingdoms:1.11.9'
|
compileOnly 'com.github.cryptomorin:kingdoms:1.11.9'
|
||||||
compileOnly 'com.github.TownyAdvanced:Towny:0.97.2.6'
|
compileOnly('com.github.TownyAdvanced:Towny:0.97.2.6') {
|
||||||
|
exclude group: 'com.zaxxer', module: 'HikariCP'
|
||||||
|
}
|
||||||
compileOnly 'com.github.angeschossen:LandsAPI:5.15.2'
|
compileOnly 'com.github.angeschossen:LandsAPI:5.15.2'
|
||||||
compileOnly 'fr.neatmonster:nocheatplus:3.16.1-SNAPSHOT'
|
compileOnly 'fr.neatmonster:nocheatplus:3.16.1-SNAPSHOT'
|
||||||
compileOnly 'com.github.jiangdashao:matrix-api-repo:317d4635fd'
|
compileOnly 'com.github.jiangdashao:matrix-api-repo:317d4635fd'
|
||||||
@@ -30,6 +32,7 @@ dependencies {
|
|||||||
compileOnly 'org.jetbrains.exposed:exposed-dao:0.36.2'
|
compileOnly 'org.jetbrains.exposed:exposed-dao:0.36.2'
|
||||||
compileOnly 'org.jetbrains.exposed:exposed-jdbc:0.36.2'
|
compileOnly 'org.jetbrains.exposed:exposed-jdbc:0.36.2'
|
||||||
compileOnly 'mysql:mysql-connector-java:8.0.25'
|
compileOnly 'mysql:mysql-connector-java:8.0.25'
|
||||||
|
compileOnly 'com.zaxxer:HikariCP:5.0.0'
|
||||||
compileOnly 'com.gmail.filoghost.holographicdisplays:holographicdisplays-api:2.4.0'
|
compileOnly 'com.gmail.filoghost.holographicdisplays:holographicdisplays-api:2.4.0'
|
||||||
compileOnly 'com.github.EssentialsX:Essentials:2.19.0'
|
compileOnly 'com.github.EssentialsX:Essentials:2.19.0'
|
||||||
compileOnly 'com.bgsoftware:SuperiorSkyblockAPI:latest'
|
compileOnly 'com.bgsoftware:SuperiorSkyblockAPI:latest'
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
package com.willfp.eco.internal.data
|
package com.willfp.eco.internal.spigot.data
|
||||||
|
|
||||||
import com.willfp.eco.core.data.PlayerProfile
|
import com.willfp.eco.core.data.PlayerProfile
|
||||||
import com.willfp.eco.core.data.keys.PersistentDataKey
|
import com.willfp.eco.core.data.keys.PersistentDataKey
|
||||||
|
import com.willfp.eco.internal.spigot.data.storage.DataHandler
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
class EcoPlayerProfile(
|
class EcoPlayerProfile(
|
||||||
val data: MutableMap<PersistentDataKey<*>, Any>,
|
val data: MutableMap<PersistentDataKey<*>, Any>,
|
||||||
val uuid: UUID
|
val uuid: UUID,
|
||||||
|
private val handler: DataHandler
|
||||||
) : PlayerProfile {
|
) : PlayerProfile {
|
||||||
override fun <T : Any> write(key: PersistentDataKey<T>, value: T) {
|
override fun <T : Any> write(key: PersistentDataKey<T>, value: T) {
|
||||||
this.data[key] = value
|
this.data[key] = value
|
||||||
@@ -19,7 +21,12 @@ class EcoPlayerProfile(
|
|||||||
|
|
||||||
override fun <T : Any> read(key: PersistentDataKey<T>): T {
|
override fun <T : Any> read(key: PersistentDataKey<T>): T {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return this.data[key] as T? ?: key.defaultValue
|
if (this.data.containsKey(key)) {
|
||||||
|
return this.data[key] as T
|
||||||
|
}
|
||||||
|
|
||||||
|
this.data[key] = handler.read(uuid, key.key) ?: key.defaultValue
|
||||||
|
return read(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
@@ -3,7 +3,6 @@ package com.willfp.eco.internal.spigot.data
|
|||||||
import com.willfp.eco.core.data.PlayerProfile
|
import com.willfp.eco.core.data.PlayerProfile
|
||||||
import com.willfp.eco.core.data.PlayerProfileHandler
|
import com.willfp.eco.core.data.PlayerProfileHandler
|
||||||
import com.willfp.eco.core.data.keys.PersistentDataKey
|
import com.willfp.eco.core.data.keys.PersistentDataKey
|
||||||
import com.willfp.eco.internal.data.EcoPlayerProfile
|
|
||||||
import com.willfp.eco.internal.spigot.data.storage.DataHandler
|
import com.willfp.eco.internal.spigot.data.storage.DataHandler
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
@@ -20,11 +19,7 @@ class EcoPlayerProfileHandler(
|
|||||||
|
|
||||||
val data = mutableMapOf<PersistentDataKey<*>, Any>()
|
val data = mutableMapOf<PersistentDataKey<*>, Any>()
|
||||||
|
|
||||||
for (key in PersistentDataKey.values()) {
|
val profile = EcoPlayerProfile(data, uuid, handler)
|
||||||
data[key] = handler.read(uuid, key.key) ?: key.defaultValue
|
|
||||||
}
|
|
||||||
|
|
||||||
val profile = EcoPlayerProfile(data, uuid)
|
|
||||||
loaded[uuid] = profile
|
loaded[uuid] = profile
|
||||||
return profile
|
return profile
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import com.willfp.eco.core.data.PlayerProfile
|
|||||||
import com.willfp.eco.core.data.keys.PersistentDataKey
|
import com.willfp.eco.core.data.keys.PersistentDataKey
|
||||||
import com.willfp.eco.core.data.keys.PersistentDataKeyType
|
import com.willfp.eco.core.data.keys.PersistentDataKeyType
|
||||||
import com.willfp.eco.internal.spigot.EcoSpigotPlugin
|
import com.willfp.eco.internal.spigot.EcoSpigotPlugin
|
||||||
|
import com.zaxxer.hikari.HikariConfig
|
||||||
|
import com.zaxxer.hikari.HikariDataSource
|
||||||
import org.apache.logging.log4j.Level
|
import org.apache.logging.log4j.Level
|
||||||
import org.bukkit.NamespacedKey
|
import org.bukkit.NamespacedKey
|
||||||
import org.jetbrains.exposed.dao.id.UUIDTable
|
import org.jetbrains.exposed.dao.id.UUIDTable
|
||||||
@@ -35,15 +37,18 @@ class MySQLDataHandler(
|
|||||||
private val executor = Executors.newFixedThreadPool(plugin.configYml.getInt("mysql.threads"), threadFactory)
|
private val executor = Executors.newFixedThreadPool(plugin.configYml.getInt("mysql.threads"), threadFactory)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
Database.connect(
|
val config = HikariConfig()
|
||||||
"jdbc:mysql://" +
|
config.driverClassName = "com.mysql.cj.jdbc.Driver"
|
||||||
"${plugin.configYml.getString("mysql.host")}:" +
|
config.username = plugin.configYml.getString("mysql.user")
|
||||||
"${plugin.configYml.getString("mysql.port")}/" +
|
config.password = plugin.configYml.getString("mysql.password")
|
||||||
plugin.configYml.getString("mysql.database"),
|
config.jdbcUrl = "jdbc:mysql://" +
|
||||||
driver = "com.mysql.cj.jdbc.Driver",
|
"${plugin.configYml.getString("mysql.host")}:" +
|
||||||
user = plugin.configYml.getString("mysql.user"),
|
"${plugin.configYml.getString("mysql.port")}/" +
|
||||||
password = plugin.configYml.getString("mysql.password")
|
plugin.configYml.getString("mysql.database")
|
||||||
)
|
config.maximumPoolSize = plugin.configYml.getInt("mysql.connections")
|
||||||
|
|
||||||
|
Database.connect(HikariDataSource(config))
|
||||||
|
|
||||||
|
|
||||||
transaction {
|
transaction {
|
||||||
SchemaUtils.create(Players)
|
SchemaUtils.create(Players)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package com.willfp.eco.internal.spigot.data.storage
|
|||||||
|
|
||||||
import com.willfp.eco.core.Eco
|
import com.willfp.eco.core.Eco
|
||||||
import com.willfp.eco.core.EcoPlugin
|
import com.willfp.eco.core.EcoPlugin
|
||||||
import com.willfp.eco.internal.data.EcoPlayerProfile
|
import com.willfp.eco.internal.spigot.data.EcoPlayerProfile
|
||||||
|
|
||||||
class ProfileSaver(plugin: EcoPlugin) {
|
class ProfileSaver(plugin: EcoPlugin) {
|
||||||
init {
|
init {
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ mysql:
|
|||||||
# very high numbers can cause issues with OS configuration. If writes are taking
|
# very high numbers can cause issues with OS configuration. If writes are taking
|
||||||
# too long, increase this value.
|
# too long, increase this value.
|
||||||
threads: 2
|
threads: 2
|
||||||
|
# The maximum number of MySQL connections.
|
||||||
|
connections: 10
|
||||||
# If read operations should be ran in the thread pool. Runs on main thread by default.
|
# If read operations should be ran in the thread pool. Runs on main thread by default.
|
||||||
async-reads: false
|
async-reads: false
|
||||||
host: localhost
|
host: localhost
|
||||||
|
|||||||
@@ -51,4 +51,5 @@ libraries:
|
|||||||
- 'org.jetbrains.exposed:exposed-dao:0.36.2'
|
- 'org.jetbrains.exposed:exposed-dao:0.36.2'
|
||||||
- 'org.jetbrains.exposed:exposed-jdbc:0.36.2'
|
- 'org.jetbrains.exposed:exposed-jdbc:0.36.2'
|
||||||
- 'mysql:mysql-connector-java:8.0.25'
|
- 'mysql:mysql-connector-java:8.0.25'
|
||||||
- 'com.google.guava:guava:31.0.1-jre'
|
- 'com.google.guava:guava:31.0.1-jre'
|
||||||
|
- 'com.zaxxer:HikariCP:5.0.0'
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
version = 6.17.1
|
version = 6.17.6
|
||||||
plugin-name = eco
|
plugin-name = eco
|
||||||
kotlin.code.style = official
|
kotlin.code.style = official
|
||||||
Reference in New Issue
Block a user