From 26105d514c88decfc9826ee955e9c558508224bf Mon Sep 17 00:00:00 2001 From: Pyrbu Date: Wed, 3 May 2023 07:24:34 +0100 Subject: [PATCH] add java 8 support (fixes #33), change folia support, restructure project --- README.md | 14 +- api/build.gradle | 1 + .../lol/pyr/znpcsplus/api/npc/NPCType.java | 4 +- build.gradle | 26 +--- folia/build.gradle | 3 - .../znpcsplus/scheduling/FoliaScheduler.java | 27 ---- settings.gradle | 2 +- spigot/build.gradle | 22 ++- .../reflection/ReflectionBuilder.java | 5 + .../znpcservers/reflection/Reflections.java | 96 ++++++++++--- .../lol/pyr/znpcsplus/hologram/Hologram.java | 6 +- .../znpcsplus/metadata/MetadataFactory.java | 2 +- .../pyr/znpcsplus/metadata/V1_13Factory.java | 4 +- .../pyr/znpcsplus/metadata/V1_8Factory.java | 4 +- .../pyr/znpcsplus/metadata/V1_9Factory.java | 4 +- .../pyr/znpcsplus/packets/PacketFactory.java | 2 +- .../pyr/znpcsplus/packets/V1_8Factory.java | 5 +- .../znpcsplus/scheduling/FoliaScheduler.java | 48 +++++++ .../znpcsplus/scheduling/TaskScheduler.java | 0 .../java/lol/pyr/znpcsplus/skin/Skin.java | 6 +- .../lol/pyr/znpcsplus/util/FoliaUtil.java | 2 + .../znpcsplus/util/list/ArrayIterator.java | 62 ++++++++ .../util/list/ImmutableArrayList.java | 133 ++++++++++++++++++ .../lol/pyr/znpcsplus/util/list/ListUtil.java | 10 ++ 24 files changed, 386 insertions(+), 102 deletions(-) delete mode 100644 folia/build.gradle delete mode 100644 folia/src/main/java/lol/pyr/znpcsplus/scheduling/FoliaScheduler.java create mode 100644 spigot/src/main/java/lol/pyr/znpcsplus/scheduling/FoliaScheduler.java rename {folia => spigot}/src/main/java/lol/pyr/znpcsplus/scheduling/TaskScheduler.java (100%) rename {folia => spigot}/src/main/java/lol/pyr/znpcsplus/util/FoliaUtil.java (76%) create mode 100644 spigot/src/main/java/lol/pyr/znpcsplus/util/list/ArrayIterator.java create mode 100644 spigot/src/main/java/lol/pyr/znpcsplus/util/list/ImmutableArrayList.java create mode 100644 spigot/src/main/java/lol/pyr/znpcsplus/util/list/ListUtil.java diff --git a/README.md b/README.md index 5fd9a66..cfc856e 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,10 @@ # ZNPCsPlus -[ZNPCsPlus](https://www.spigotmc.org/resources/znpcsplus.109380/) is an unofficial fork of the popular NPC plugin ZNPCs written with the Spigot/Bukkit API originally made by -gonalez/ZNetwork. This fork was made because the original maintainer of the plugin decided to announce that he was -[dropping support for the plugin](https://media.discordapp.net/attachments/1093914615873806477/1098409384855474237/znpc.png) -in the original project's [official discord server](https://discord.com/invite/RhNMH4T). +[ZNPCsPlus](https://www.spigotmc.org/resources/znpcsplus.109380/) is an remake of the popular NPC plugin ZNPCs written with the Spigot/Bukkit API originally made by +gonalez/ZNetwork. This project was originally started because the maintainer of ZNPCs decided to announce that he was +[dropping support for the plugin](https://media.discordapp.net/attachments/1093914615873806477/1098409384855474237/znpc.png). ### Dependencies -- Java 17 +- Java 8 - Spigot 1.8 - 1.19.4 - PlaceholderAPI (OPTIONAL) @@ -15,7 +14,10 @@ If you're using a Minecraft version that rejects Java 17 use the `-DPaper.Ignore This fork makes several improvements over the original including: - More performance-conscious code - Latest version support (1.19.4) -- Fixes for long-running issues of the original plugin (ones that the original maintainer refused to even acknowledge) +- Fixes for long-running issues of the original plugin +- Better stability +- Support for multiple different storage options (WIP) +- Better command system (WIP) ## Found a bug? Open an issue in the GitHub [issue tracker](https://github.com/Pyrbu/ZNPCsPlus/issues) diff --git a/api/build.gradle b/api/build.gradle index 838d35a..f6b0d20 100644 --- a/api/build.gradle +++ b/api/build.gradle @@ -1,4 +1,5 @@ plugins { + id "java" id "maven-publish" } diff --git a/api/src/main/java/lol/pyr/znpcsplus/api/npc/NPCType.java b/api/src/main/java/lol/pyr/znpcsplus/api/npc/NPCType.java index 2f8e75c..4cc9a3f 100644 --- a/api/src/main/java/lol/pyr/znpcsplus/api/npc/NPCType.java +++ b/api/src/main/java/lol/pyr/znpcsplus/api/npc/NPCType.java @@ -86,7 +86,7 @@ public class NPCType { } public Builder addProperties(EntityProperty... properties) { - allowedProperties.addAll(List.of(properties)); + allowedProperties.addAll(Arrays.asList(properties)); return this; } @@ -108,7 +108,7 @@ public class NPCType { if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) allowedProperties.add(EntityProperty.GLOW); } - return new NPCType(name, type, hologramOffset, Set.copyOf(allowedProperties)); + return new NPCType(name, type, hologramOffset, new HashSet<>(allowedProperties)); } } } diff --git a/build.gradle b/build.gradle index dec00de..36a20c6 100644 --- a/build.gradle +++ b/build.gradle @@ -1,27 +1,11 @@ -plugins { - id "java" - id "com.github.johnrengelman.shadow" version "8.1.1" - id "xyz.jpenilla.run-paper" version "2.0.1" -} - -dependencies { - implementation project(path: ":spigot", configuration: "shadow") - implementation project(":api") - implementation project(":folia") -} - -runServer { - minecraftVersion "1.19.4" -} - -allprojects { +subprojects { apply plugin: "java" group "lol.pyr" version "2.0.0" compileJava { - options.release.set(17) + options.release.set(8) } repositories { @@ -32,6 +16,9 @@ allprojects { maven { url "https://repo.codemc.io/repository/maven-snapshots/" } + maven { + url "https://libraries.minecraft.net" + } maven { url "https://repo.papermc.io/repository/maven-public/" } @@ -46,6 +33,3 @@ allprojects { } } } - -tasks.assemble.dependsOn shadowJar -tasks.compileJava.dependsOn clean \ No newline at end of file diff --git a/folia/build.gradle b/folia/build.gradle deleted file mode 100644 index cc0ecff..0000000 --- a/folia/build.gradle +++ /dev/null @@ -1,3 +0,0 @@ -dependencies { - compileOnly "dev.folia:folia-api:1.19.4-R0.1-SNAPSHOT" -} diff --git a/folia/src/main/java/lol/pyr/znpcsplus/scheduling/FoliaScheduler.java b/folia/src/main/java/lol/pyr/znpcsplus/scheduling/FoliaScheduler.java deleted file mode 100644 index c2b145a..0000000 --- a/folia/src/main/java/lol/pyr/znpcsplus/scheduling/FoliaScheduler.java +++ /dev/null @@ -1,27 +0,0 @@ -package lol.pyr.znpcsplus.scheduling; - -import org.bukkit.Bukkit; -import org.bukkit.plugin.Plugin; - -import java.util.concurrent.TimeUnit; - -public class FoliaScheduler extends TaskScheduler { - public FoliaScheduler(Plugin plugin) { - super(plugin); - } - - @Override - public void runAsync(Runnable runnable) { - Bukkit.getAsyncScheduler().runNow(plugin, task -> runnable.run()); - } - - @Override - public void runLaterAsync(Runnable runnable, long ticks) { - Bukkit.getAsyncScheduler().runDelayed(plugin, task -> runnable.run(), ticks * 50, TimeUnit.MILLISECONDS); - } - - @Override - public void runDelayedTimerAsync(Runnable runnable, long delay, long ticks) { - Bukkit.getAsyncScheduler().runAtFixedRate(plugin, task -> runnable.run(), delay * 50, ticks * 50, TimeUnit.MILLISECONDS); - } -} diff --git a/settings.gradle b/settings.gradle index fea8846..819ba16 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,3 +1,3 @@ rootProject.name = "ZNPCsPlus" -include "api", "spigot", "folia" \ No newline at end of file +include "api", "spigot" \ No newline at end of file diff --git a/spigot/build.gradle b/spigot/build.gradle index a592674..2382f85 100644 --- a/spigot/build.gradle +++ b/spigot/build.gradle @@ -1,12 +1,22 @@ plugins { + id "java" id "com.github.johnrengelman.shadow" version "8.1.1" + id "xyz.jpenilla.run-paper" version "2.0.1" +} + +runServer { + minecraftVersion "1.19.4" +} + +processResources { + expand("version": version) } dependencies { compileOnly "org.spigotmc:spigot-api:1.19.4-R0.1-SNAPSHOT" compileOnly "me.clip:placeholderapi:2.11.1" - compileOnly "com.mojang:authlib:3.4.40" + compileOnly "com.mojang:authlib:1.5.21" compileOnly "com.mojang:datafixerupper:4.0.26" implementation "commons-io:commons-io:2.11.0" @@ -19,13 +29,13 @@ dependencies { implementation "space.arim.dazzleconf:dazzleconf-ext-snakeyaml:1.2.1" implementation "lol.pyr:director-adventure:2.0.1" - - compileOnly project(":api") - compileOnly project(":folia") + implementation project(":api") } shadowJar { + archivesBaseName = "ZNPCsPlus" archiveClassifier.set "" + relocate "org.bstats", "lol.pyr.znpcsplus.lib.bstats" relocate "org.apache.commons.io", "lol.pyr.znpcsplus.lib.commonsio" relocate "me.robertlit.spigotresources", "lol.pyr.znpcsplus.lib.spigotresources" @@ -42,4 +52,6 @@ shadowJar { relocate "lol.pyr.director", "lol.pyr.znpcsplus.lib.command" minimize() -} \ No newline at end of file +} + +tasks.assemble.dependsOn shadowJar \ No newline at end of file diff --git a/spigot/src/main/java/io/github/znetworkw/znpcservers/reflection/ReflectionBuilder.java b/spigot/src/main/java/io/github/znetworkw/znpcservers/reflection/ReflectionBuilder.java index c4e3fb3..b39ce6a 100644 --- a/spigot/src/main/java/io/github/znetworkw/znpcservers/reflection/ReflectionBuilder.java +++ b/spigot/src/main/java/io/github/znetworkw/znpcservers/reflection/ReflectionBuilder.java @@ -15,6 +15,11 @@ public class ReflectionBuilder { private Class expectType; private boolean strict = true; + public ReflectionBuilder(Class clazz) { + this(""); + withClassName(clazz); + } + public ReflectionBuilder(String reflectionPackage) { this(reflectionPackage, "", "", null); } diff --git a/spigot/src/main/java/io/github/znetworkw/znpcservers/reflection/Reflections.java b/spigot/src/main/java/io/github/znetworkw/znpcservers/reflection/Reflections.java index c6cf81a..47259db 100644 --- a/spigot/src/main/java/io/github/znetworkw/znpcservers/reflection/Reflections.java +++ b/spigot/src/main/java/io/github/znetworkw/znpcservers/reflection/Reflections.java @@ -5,40 +5,92 @@ import io.github.znetworkw.znpcservers.reflection.types.ClassReflection; import io.github.znetworkw.znpcservers.reflection.types.FieldReflection; import io.github.znetworkw.znpcservers.reflection.types.MethodReflection; import io.github.znetworkw.znpcservers.utility.Utils; +import lol.pyr.znpcsplus.util.FoliaUtil; +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; import java.lang.reflect.Method; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; /** * Class containing all of the lazy-loaded reflections that the plugin * uses to accessinaccessible things from the server jar. */ public final class Reflections { - public static final Class ENTITY_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY) - .withClassName("Entity")).get(); + public static final Class ENTITY_CLASS = new ClassReflection( + new ReflectionBuilder(ReflectionPackage.ENTITY) + .withClassName("Entity")).get(); - public static final Class ENTITY_HUMAN_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY) - .withSubClass("player") - .withClassName("EntityHuman")).get(); + public static final Class ENTITY_HUMAN_CLASS = new ClassReflection( + new ReflectionBuilder(ReflectionPackage.ENTITY) + .withSubClass("player") + .withClassName("EntityHuman")).get(); - public static final ReflectionLazyLoader GET_PROFILE_METHOD = new MethodReflection(new ReflectionBuilder(ReflectionPackage.ENTITY) - .withClassName(ENTITY_HUMAN_CLASS) - .withExpectResult(GameProfile.class)); + public static final ReflectionLazyLoader GET_PROFILE_METHOD = new MethodReflection( + new ReflectionBuilder(ReflectionPackage.ENTITY) + .withClassName(ENTITY_HUMAN_CLASS) + .withExpectResult(GameProfile.class)); - public static final ReflectionLazyLoader GET_HANDLE_PLAYER_METHOD = new MethodReflection(new ReflectionBuilder(ReflectionPackage.BUKKIT) - .withClassName("entity.CraftPlayer").withClassName("entity.CraftHumanEntity") - .withMethodName("getHandle")); + public static final ReflectionLazyLoader GET_HANDLE_PLAYER_METHOD = new MethodReflection( + new ReflectionBuilder(ReflectionPackage.BUKKIT) + .withClassName("entity.CraftPlayer").withClassName("entity.CraftHumanEntity") + .withMethodName("getHandle")); - public static final FieldReflection.ValueModifier ENTITY_ID_MODIFIER = new FieldReflection(new ReflectionBuilder(ReflectionPackage.ENTITY) - .withClassName(ENTITY_CLASS) - .withFieldName("entityCount") - .setStrict(!Utils.versionNewer(14))).staticValueModifier(int.class); + public static final FieldReflection.ValueModifier ENTITY_ID_MODIFIER = new FieldReflection( + new ReflectionBuilder(ReflectionPackage.ENTITY) + .withClassName(ENTITY_CLASS) + .withFieldName("entityCount") + .setStrict(!Utils.versionNewer(14))).staticValueModifier(int.class); - public static final ReflectionLazyLoader ATOMIC_ENTITY_ID_FIELD = new FieldReflection(new ReflectionBuilder(ReflectionPackage.ENTITY) - .withClassName(ENTITY_CLASS) - .withFieldName("entityCount") - .withFieldName("d") - .withFieldName("c") - .withExpectResult(AtomicInteger.class) - .setStrict(Utils.versionNewer(14))).staticValueLoader(AtomicInteger.class); + public static final ReflectionLazyLoader ATOMIC_ENTITY_ID_FIELD = new FieldReflection( + new ReflectionBuilder(ReflectionPackage.ENTITY) + .withClassName(ENTITY_CLASS) + .withFieldName("entityCount") + .withFieldName("d") + .withFieldName("c") + .withExpectResult(AtomicInteger.class) + .setStrict(Utils.versionNewer(14))).staticValueLoader(AtomicInteger.class); + + public static final Class ASYNC_SCHEDULER_CLASS = new ClassReflection( + new ReflectionBuilder("io.papermc.paper.threadedregions.scheduler") + .withClassName("AsyncScheduler") + .setStrict(FoliaUtil.isFolia())).get(); + + public static final Class SCHEDULED_TASK_CLASS = new ClassReflection( + new ReflectionBuilder("io.papermc.paper.threadedregions.scheduler") + .withClassName("ScheduledTask") + .setStrict(FoliaUtil.isFolia())).get(); + + public static final ReflectionLazyLoader FOLIA_GET_ASYNC_SCHEDULER = new MethodReflection( + new ReflectionBuilder(Bukkit.class) + .withMethodName("getAsyncScheduler") + .withExpectResult(ASYNC_SCHEDULER_CLASS) + .setStrict(FoliaUtil.isFolia())); + + public static final ReflectionLazyLoader FOLIA_RUN_NOW = new MethodReflection( + new ReflectionBuilder(ASYNC_SCHEDULER_CLASS) + .withMethodName("runNow") + .withParameterTypes(Plugin.class, Consumer.class) + .withExpectResult(SCHEDULED_TASK_CLASS) + .setStrict(FoliaUtil.isFolia())); + + public static final ReflectionLazyLoader FOLIA_RUN_DELAYED = new MethodReflection( + new ReflectionBuilder(ASYNC_SCHEDULER_CLASS) + .withMethodName("runDelayed") + .withParameterTypes(Plugin.class, Consumer.class, long.class, TimeUnit.class) + .withExpectResult(SCHEDULED_TASK_CLASS) + .setStrict(FoliaUtil.isFolia())); + + public static final ReflectionLazyLoader FOLIA_RUN_AT_FIXED_RATE = new MethodReflection( + new ReflectionBuilder(ASYNC_SCHEDULER_CLASS) + .withMethodName("runAtFixedRate") + .withParameterTypes(Plugin.class, Consumer.class, long.class, long.class, TimeUnit.class) + .withExpectResult(SCHEDULED_TASK_CLASS) + .setStrict(FoliaUtil.isFolia())); } + +// Bukkit.getAsyncScheduler().runNow(plugin, task -> runnable.run()); +// Bukkit.getAsyncScheduler().runDelayed(plugin, task -> runnable.run(), ticks * 50, TimeUnit.MILLISECONDS); +// Bukkit.getAsyncScheduler().runAtFixedRate(plugin, task -> runnable.run(), delay * 50, ticks * 50, TimeUnit.MILLISECONDS); diff --git a/spigot/src/main/java/lol/pyr/znpcsplus/hologram/Hologram.java b/spigot/src/main/java/lol/pyr/znpcsplus/hologram/Hologram.java index 9af424e..027a394 100644 --- a/spigot/src/main/java/lol/pyr/znpcsplus/hologram/Hologram.java +++ b/spigot/src/main/java/lol/pyr/znpcsplus/hologram/Hologram.java @@ -1,14 +1,14 @@ package lol.pyr.znpcsplus.hologram; import lol.pyr.znpcsplus.config.Configs; -import lol.pyr.znpcsplus.util.ZLocation; import lol.pyr.znpcsplus.util.Viewable; +import lol.pyr.znpcsplus.util.ZLocation; import net.kyori.adventure.text.Component; import org.bukkit.entity.Player; import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import java.util.Set; public class Hologram extends Viewable implements lol.pyr.znpcsplus.api.hologram.Hologram { private ZLocation location; @@ -70,7 +70,7 @@ public class Hologram extends Viewable implements lol.pyr.znpcsplus.api.hologram final double lineSpacing = Configs.config().lineSpacing(); double height = location.getY() + lines.size() * lineSpacing; for (HologramLine line : lines) { - line.setLocation(location.withY(height), line == newLine ? Set.of() : getViewers()); + line.setLocation(location.withY(height), line == newLine ? Collections.emptySet() : getViewers()); height -= lineSpacing; } } diff --git a/spigot/src/main/java/lol/pyr/znpcsplus/metadata/MetadataFactory.java b/spigot/src/main/java/lol/pyr/znpcsplus/metadata/MetadataFactory.java index 95abc45..35e1bd2 100644 --- a/spigot/src/main/java/lol/pyr/znpcsplus/metadata/MetadataFactory.java +++ b/spigot/src/main/java/lol/pyr/znpcsplus/metadata/MetadataFactory.java @@ -48,7 +48,7 @@ public interface MetadataFactory { throw new RuntimeException("Unsupported version!"); } - private static Map> buildFactoryMap() { + static Map> buildFactoryMap() { HashMap> map = new HashMap<>(); map.put(ServerVersion.V_1_8, LazyLoader.of(V1_8Factory::new)); map.put(ServerVersion.V_1_9, LazyLoader.of(V1_9Factory::new)); diff --git a/spigot/src/main/java/lol/pyr/znpcsplus/metadata/V1_13Factory.java b/spigot/src/main/java/lol/pyr/znpcsplus/metadata/V1_13Factory.java index 0f1d89c..9358011 100644 --- a/spigot/src/main/java/lol/pyr/znpcsplus/metadata/V1_13Factory.java +++ b/spigot/src/main/java/lol/pyr/znpcsplus/metadata/V1_13Factory.java @@ -3,16 +3,16 @@ package lol.pyr.znpcsplus.metadata; import com.github.retrooper.packetevents.protocol.entity.data.EntityData; import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes; import com.github.retrooper.packetevents.util.adventure.AdventureSerializer; +import lol.pyr.znpcsplus.util.list.ListUtil; import net.kyori.adventure.text.Component; import java.util.Collection; -import java.util.List; import java.util.Optional; public class V1_13Factory extends V1_9Factory { @Override public Collection name(Component name) { - return List.of( + return ListUtil.immutableList( new EntityData(2, EntityDataTypes.OPTIONAL_COMPONENT, Optional.of(AdventureSerializer.getGsonSerializer().serialize(name))), new EntityData(3, EntityDataTypes.BOOLEAN, true) ); diff --git a/spigot/src/main/java/lol/pyr/znpcsplus/metadata/V1_8Factory.java b/spigot/src/main/java/lol/pyr/znpcsplus/metadata/V1_8Factory.java index f170001..cb05973 100644 --- a/spigot/src/main/java/lol/pyr/znpcsplus/metadata/V1_8Factory.java +++ b/spigot/src/main/java/lol/pyr/znpcsplus/metadata/V1_8Factory.java @@ -3,10 +3,10 @@ package lol.pyr.znpcsplus.metadata; import com.github.retrooper.packetevents.protocol.entity.data.EntityData; import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes; import com.github.retrooper.packetevents.util.adventure.AdventureSerializer; +import lol.pyr.znpcsplus.util.list.ListUtil; import net.kyori.adventure.text.Component; import java.util.Collection; -import java.util.List; public class V1_8Factory implements MetadataFactory { @Override @@ -21,7 +21,7 @@ public class V1_8Factory implements MetadataFactory { @Override public Collection name(Component name) { - return List.of( + return ListUtil.immutableList( new EntityData(2, EntityDataTypes.STRING, AdventureSerializer.getGsonSerializer().serialize(name)), new EntityData(3, EntityDataTypes.BYTE, 1) ); diff --git a/spigot/src/main/java/lol/pyr/znpcsplus/metadata/V1_9Factory.java b/spigot/src/main/java/lol/pyr/znpcsplus/metadata/V1_9Factory.java index 49fb334..48452ee 100644 --- a/spigot/src/main/java/lol/pyr/znpcsplus/metadata/V1_9Factory.java +++ b/spigot/src/main/java/lol/pyr/znpcsplus/metadata/V1_9Factory.java @@ -3,10 +3,10 @@ package lol.pyr.znpcsplus.metadata; import com.github.retrooper.packetevents.protocol.entity.data.EntityData; import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes; import com.github.retrooper.packetevents.util.adventure.AdventureSerializer; +import lol.pyr.znpcsplus.util.list.ListUtil; import net.kyori.adventure.text.Component; import java.util.Collection; -import java.util.List; public class V1_9Factory extends V1_8Factory { @Override @@ -21,7 +21,7 @@ public class V1_9Factory extends V1_8Factory { @Override public Collection name(Component name) { - return List.of( + return ListUtil.immutableList( new EntityData(2, EntityDataTypes.STRING, AdventureSerializer.getGsonSerializer().serialize(name)), new EntityData(3, EntityDataTypes.BOOLEAN, true) ); diff --git a/spigot/src/main/java/lol/pyr/znpcsplus/packets/PacketFactory.java b/spigot/src/main/java/lol/pyr/znpcsplus/packets/PacketFactory.java index d71ff7d..f1d434c 100644 --- a/spigot/src/main/java/lol/pyr/znpcsplus/packets/PacketFactory.java +++ b/spigot/src/main/java/lol/pyr/znpcsplus/packets/PacketFactory.java @@ -43,7 +43,7 @@ public interface PacketFactory { throw new RuntimeException("Unsupported version!"); } - private static Map> buildFactoryMap() { + static Map> buildFactoryMap() { HashMap> map = new HashMap<>(); map.put(ServerVersion.V_1_8, LazyLoader.of(V1_8Factory::new)); map.put(ServerVersion.V_1_9, LazyLoader.of(V1_9Factory::new)); diff --git a/spigot/src/main/java/lol/pyr/znpcsplus/packets/V1_8Factory.java b/spigot/src/main/java/lol/pyr/znpcsplus/packets/V1_8Factory.java index 9f3293a..af561da 100644 --- a/spigot/src/main/java/lol/pyr/znpcsplus/packets/V1_8Factory.java +++ b/spigot/src/main/java/lol/pyr/znpcsplus/packets/V1_8Factory.java @@ -22,6 +22,7 @@ import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.entity.Player; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.concurrent.CompletableFuture; @@ -33,7 +34,7 @@ public class V1_8Factory implements PacketFactory { createTeam(player, entity, properties); ZLocation location = entity.getLocation(); sendPacket(player, new WrapperPlayServerSpawnPlayer(entity.getEntityId(), - entity.getUuid(), location.toVector3d(), location.getYaw(), location.getPitch(), List.of())); + entity.getUuid(), location.toVector3d(), location.getYaw(), location.getPitch(), Collections.emptyList())); sendAllMetadata(player, entity, properties); ZNPCsPlus.SCHEDULER.runLaterAsync(() -> removeTabPlayer(player, entity), 60); }); @@ -46,7 +47,7 @@ public class V1_8Factory implements PacketFactory { ClientVersion clientVersion = PacketEvents.getAPI().getServerManager().getVersion().toClientVersion(); sendPacket(player, type.getLegacyId(clientVersion) == -1 ? new WrapperPlayServerSpawnLivingEntity(entity.getEntityId(), entity.getUuid(), type, location.toVector3d(), - location.getYaw(), location.getPitch(), location.getPitch(), new Vector3d(), List.of()) : + location.getYaw(), location.getPitch(), location.getPitch(), new Vector3d(), Collections.emptyList()) : new WrapperPlayServerSpawnEntity(entity.getEntityId(), Optional.of(entity.getUuid()), entity.getType(), location.toVector3d(), location.getPitch(), location.getYaw(), location.getYaw(), 0, Optional.empty())); sendAllMetadata(player, entity, properties); diff --git a/spigot/src/main/java/lol/pyr/znpcsplus/scheduling/FoliaScheduler.java b/spigot/src/main/java/lol/pyr/znpcsplus/scheduling/FoliaScheduler.java new file mode 100644 index 0000000..b6c6afb --- /dev/null +++ b/spigot/src/main/java/lol/pyr/znpcsplus/scheduling/FoliaScheduler.java @@ -0,0 +1,48 @@ +package lol.pyr.znpcsplus.scheduling; + +import io.github.znetworkw.znpcservers.reflection.Reflections; +import org.bukkit.plugin.Plugin; + +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; + +public class FoliaScheduler extends TaskScheduler { + public FoliaScheduler(Plugin plugin) { + super(plugin); + } + + @Override + public void runAsync(Runnable runnable) { + try { + Object scheduler = Reflections.FOLIA_GET_ASYNC_SCHEDULER.get().invoke(null); + Reflections.FOLIA_RUN_NOW.get().invoke(scheduler, plugin, (Consumer) o -> runnable.run()); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + // Bukkit.getAsyncScheduler().runNow(plugin, task -> runnable.run()); + } + + @Override + public void runLaterAsync(Runnable runnable, long ticks) { + try { + Object scheduler = Reflections.FOLIA_GET_ASYNC_SCHEDULER.get().invoke(null); + Reflections.FOLIA_RUN_DELAYED.get().invoke(scheduler, plugin, (Consumer) o -> runnable.run(), ticks * 50, TimeUnit.MILLISECONDS); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + // Bukkit.getAsyncScheduler().runDelayed(plugin, task -> runnable.run(), ticks * 50, TimeUnit.MILLISECONDS); + } + + @Override + public void runDelayedTimerAsync(Runnable runnable, long delay, long ticks) { + try { + Object scheduler = Reflections.FOLIA_GET_ASYNC_SCHEDULER.get().invoke(null); + Reflections.FOLIA_RUN_AT_FIXED_RATE.get().invoke(scheduler, plugin, (Consumer) o -> runnable.run(), delay * 50, ticks * 50, TimeUnit.MILLISECONDS); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + // Bukkit.getAsyncScheduler().runAtFixedRate(plugin, task -> runnable.run(), delay * 50, ticks * 50, TimeUnit.MILLISECONDS); + } +} + diff --git a/folia/src/main/java/lol/pyr/znpcsplus/scheduling/TaskScheduler.java b/spigot/src/main/java/lol/pyr/znpcsplus/scheduling/TaskScheduler.java similarity index 100% rename from folia/src/main/java/lol/pyr/znpcsplus/scheduling/TaskScheduler.java rename to spigot/src/main/java/lol/pyr/znpcsplus/scheduling/TaskScheduler.java diff --git a/spigot/src/main/java/lol/pyr/znpcsplus/skin/Skin.java b/spigot/src/main/java/lol/pyr/znpcsplus/skin/Skin.java index 7954304..ff0ed16 100644 --- a/spigot/src/main/java/lol/pyr/znpcsplus/skin/Skin.java +++ b/spigot/src/main/java/lol/pyr/znpcsplus/skin/Skin.java @@ -5,9 +5,11 @@ import com.github.retrooper.packetevents.protocol.player.UserProfile; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.mojang.authlib.properties.PropertyMap; +import lol.pyr.znpcsplus.util.list.ListUtil; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; public class Skin { private final long timestamp = System.currentTimeMillis(); @@ -18,13 +20,13 @@ public class Skin { } public Skin(TextureProperty... properties) { - this.properties.addAll(List.of(properties)); + this.properties.addAll(ListUtil.immutableList(properties)); } public Skin(PropertyMap properties) { this.properties.addAll(properties.values().stream() .map(property -> new TextureProperty(property.getName(), property.getValue(), property.getSignature())) - .toList()); + .collect(Collectors.toList())); } public Skin(JsonObject obj) { diff --git a/folia/src/main/java/lol/pyr/znpcsplus/util/FoliaUtil.java b/spigot/src/main/java/lol/pyr/znpcsplus/util/FoliaUtil.java similarity index 76% rename from folia/src/main/java/lol/pyr/znpcsplus/util/FoliaUtil.java rename to spigot/src/main/java/lol/pyr/znpcsplus/util/FoliaUtil.java index ecbba61..309310b 100644 --- a/folia/src/main/java/lol/pyr/znpcsplus/util/FoliaUtil.java +++ b/spigot/src/main/java/lol/pyr/znpcsplus/util/FoliaUtil.java @@ -1,7 +1,9 @@ package lol.pyr.znpcsplus.util; public class FoliaUtil { + private static final Boolean FOLIA = isFolia(); public static boolean isFolia() { + if (FOLIA != null) return FOLIA; try { Class.forName("io.papermc.paper.threadedregions.RegionizedServer"); return true; diff --git a/spigot/src/main/java/lol/pyr/znpcsplus/util/list/ArrayIterator.java b/spigot/src/main/java/lol/pyr/znpcsplus/util/list/ArrayIterator.java new file mode 100644 index 0000000..8081617 --- /dev/null +++ b/spigot/src/main/java/lol/pyr/znpcsplus/util/list/ArrayIterator.java @@ -0,0 +1,62 @@ +package lol.pyr.znpcsplus.util.list; + +import java.util.Iterator; +import java.util.ListIterator; + +public class ArrayIterator implements Iterator, ListIterator { + private final T[] array; + private int index = 0; + + public ArrayIterator(T[] array) { + this.array = array; + } + + @Override + public boolean hasNext() { + return array.length > index; + } + + @Override + public T next() { + return array[index++]; + } + + private boolean inBounds(int index) { + return index >= 0 && index < array.length; + } + + @Override + public boolean hasPrevious() { + return inBounds(index - 1); + } + + @Override + public T previous() { + return array[--index]; + } + + @Override + public int nextIndex() { + return index + 1; + } + + @Override + public int previousIndex() { + return index - 1; + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + @Override + public void set(T t) { + throw new UnsupportedOperationException(); + } + + @Override + public void add(T t) { + throw new UnsupportedOperationException(); + } +} diff --git a/spigot/src/main/java/lol/pyr/znpcsplus/util/list/ImmutableArrayList.java b/spigot/src/main/java/lol/pyr/znpcsplus/util/list/ImmutableArrayList.java new file mode 100644 index 0000000..1decdbb --- /dev/null +++ b/spigot/src/main/java/lol/pyr/znpcsplus/util/list/ImmutableArrayList.java @@ -0,0 +1,133 @@ +package lol.pyr.znpcsplus.util.list; + +import java.util.*; + +public class ImmutableArrayList implements List { + private final T[] elements; + + public ImmutableArrayList(T[] array) { + this.elements = array; + } + + @Override + public int size() { + return elements.length; + } + + @Override + public boolean isEmpty() { + return elements.length != 0; + } + + @Override + public boolean contains(Object o) { + return indexOf(o) != -1; + } + + @Override + public Iterator iterator() { + return new ArrayIterator<>(elements); + } + + @Override + public Object[] toArray() { + return elements; + } + + @SuppressWarnings("unchecked") + @Override + public T1[] toArray(T1[] a) { + return (T1[]) elements; + } + + @Override + public boolean containsAll(Collection c) { + for (Object obj : c) if (!contains(obj)) return false; + return true; + } + + @Override + public List subList(int fromIndex, int toIndex) { + return new ImmutableArrayList<>(Arrays.copyOfRange(elements, fromIndex, toIndex)); + } + + @Override + public T get(int index) { + return elements[index]; + } + + @Override + public int indexOf(Object o) { + for (int i = 0; i < elements.length; i++) if (Objects.equals(elements[i], o)) return i; + return -1; + } + + @Override + public int lastIndexOf(Object o) { + for (int i = 0; i < elements.length; i++) { + int index = elements.length - (i + 1); + if (Objects.equals(elements[index], o)) return index; + } + return -1; + } + + @Override + public ListIterator listIterator() { + return new ArrayIterator<>(elements); + } + + @Override + public ListIterator listIterator(int index) { + return new ArrayIterator<>(elements); + } + + @Override + public boolean add(T t) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean remove(Object o) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean addAll(Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean addAll(int index, Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean removeAll(Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean retainAll(Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public void clear() { + throw new UnsupportedOperationException(); + } + + @Override + public T set(int index, T element) { + throw new UnsupportedOperationException(); + } + + @Override + public void add(int index, T element) { + throw new UnsupportedOperationException(); + } + + @Override + public T remove(int index) { + throw new UnsupportedOperationException(); + } +} \ No newline at end of file diff --git a/spigot/src/main/java/lol/pyr/znpcsplus/util/list/ListUtil.java b/spigot/src/main/java/lol/pyr/znpcsplus/util/list/ListUtil.java new file mode 100644 index 0000000..faa6898 --- /dev/null +++ b/spigot/src/main/java/lol/pyr/znpcsplus/util/list/ListUtil.java @@ -0,0 +1,10 @@ +package lol.pyr.znpcsplus.util.list; + +import java.util.*; + +public class ListUtil { + @SafeVarargs + public static List immutableList(T... elements) { + return new ImmutableArrayList<>(elements); + } +}