add java 8 support (fixes #33), change folia support, restructure project
This commit is contained in:
		
							parent
							
								
									b3c9b246c7
								
							
						
					
					
						commit
						26105d514c
					
				
					 24 changed files with 386 additions and 102 deletions
				
			
		
							
								
								
									
										14
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								README.md
									
									
									
									
									
								
							| 
						 | 
					@ -1,11 +1,10 @@
 | 
				
			||||||
# ZNPCsPlus
 | 
					# 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 
 | 
					[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 fork was made because the original maintainer of the plugin decided to announce that he was 
 | 
					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) 
 | 
					[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).
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Dependencies
 | 
					### Dependencies
 | 
				
			||||||
- Java 17
 | 
					- Java 8
 | 
				
			||||||
- Spigot 1.8 - 1.19.4
 | 
					- Spigot 1.8 - 1.19.4
 | 
				
			||||||
- PlaceholderAPI (OPTIONAL)
 | 
					- 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:
 | 
					This fork makes several improvements over the original including:
 | 
				
			||||||
- More performance-conscious code
 | 
					- More performance-conscious code
 | 
				
			||||||
- Latest version support (1.19.4)
 | 
					- 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?
 | 
					## Found a bug?
 | 
				
			||||||
Open an issue in the GitHub [issue tracker](https://github.com/Pyrbu/ZNPCsPlus/issues)
 | 
					Open an issue in the GitHub [issue tracker](https://github.com/Pyrbu/ZNPCsPlus/issues)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,5 @@
 | 
				
			||||||
plugins {
 | 
					plugins {
 | 
				
			||||||
 | 
					    id "java"
 | 
				
			||||||
    id "maven-publish"
 | 
					    id "maven-publish"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -86,7 +86,7 @@ public class NPCType {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public Builder addProperties(EntityProperty<?>... properties) {
 | 
					        public Builder addProperties(EntityProperty<?>... properties) {
 | 
				
			||||||
            allowedProperties.addAll(List.of(properties));
 | 
					            allowedProperties.addAll(Arrays.asList(properties));
 | 
				
			||||||
            return this;
 | 
					            return this;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -108,7 +108,7 @@ public class NPCType {
 | 
				
			||||||
                if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_9))
 | 
					                if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_9))
 | 
				
			||||||
                    allowedProperties.add(EntityProperty.GLOW);
 | 
					                    allowedProperties.add(EntityProperty.GLOW);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return new NPCType(name, type, hologramOffset, Set.copyOf(allowedProperties));
 | 
					            return new NPCType(name, type, hologramOffset, new HashSet<>(allowedProperties));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										26
									
								
								build.gradle
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								build.gradle
									
									
									
									
									
								
							| 
						 | 
					@ -1,27 +1,11 @@
 | 
				
			||||||
plugins {
 | 
					subprojects {
 | 
				
			||||||
    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 {
 | 
					 | 
				
			||||||
    apply plugin: "java"
 | 
					    apply plugin: "java"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    group "lol.pyr"
 | 
					    group "lol.pyr"
 | 
				
			||||||
    version "2.0.0"
 | 
					    version "2.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    compileJava {
 | 
					    compileJava {
 | 
				
			||||||
        options.release.set(17)
 | 
					        options.release.set(8)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    repositories {
 | 
					    repositories {
 | 
				
			||||||
| 
						 | 
					@ -32,6 +16,9 @@ allprojects {
 | 
				
			||||||
        maven {
 | 
					        maven {
 | 
				
			||||||
            url "https://repo.codemc.io/repository/maven-snapshots/"
 | 
					            url "https://repo.codemc.io/repository/maven-snapshots/"
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        maven {
 | 
				
			||||||
 | 
					            url "https://libraries.minecraft.net"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        maven {
 | 
					        maven {
 | 
				
			||||||
            url "https://repo.papermc.io/repository/maven-public/"
 | 
					            url "https://repo.papermc.io/repository/maven-public/"
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -46,6 +33,3 @@ allprojects {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
tasks.assemble.dependsOn shadowJar
 | 
					 | 
				
			||||||
tasks.compileJava.dependsOn clean
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,3 +0,0 @@
 | 
				
			||||||
dependencies {
 | 
					 | 
				
			||||||
    compileOnly "dev.folia:folia-api:1.19.4-R0.1-SNAPSHOT"
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,3 +1,3 @@
 | 
				
			||||||
rootProject.name = "ZNPCsPlus"
 | 
					rootProject.name = "ZNPCsPlus"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
include "api", "spigot", "folia"
 | 
					include "api", "spigot"
 | 
				
			||||||
| 
						 | 
					@ -1,12 +1,22 @@
 | 
				
			||||||
plugins {
 | 
					plugins {
 | 
				
			||||||
 | 
					    id "java"
 | 
				
			||||||
    id "com.github.johnrengelman.shadow" version "8.1.1"
 | 
					    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 {
 | 
					dependencies {
 | 
				
			||||||
    compileOnly "org.spigotmc:spigot-api:1.19.4-R0.1-SNAPSHOT"
 | 
					    compileOnly "org.spigotmc:spigot-api:1.19.4-R0.1-SNAPSHOT"
 | 
				
			||||||
    compileOnly "me.clip:placeholderapi:2.11.1"
 | 
					    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"
 | 
					    compileOnly "com.mojang:datafixerupper:4.0.26"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    implementation "commons-io:commons-io:2.11.0"
 | 
					    implementation "commons-io:commons-io:2.11.0"
 | 
				
			||||||
| 
						 | 
					@ -19,13 +29,13 @@ dependencies {
 | 
				
			||||||
    implementation "space.arim.dazzleconf:dazzleconf-ext-snakeyaml:1.2.1"
 | 
					    implementation "space.arim.dazzleconf:dazzleconf-ext-snakeyaml:1.2.1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    implementation "lol.pyr:director-adventure:2.0.1"
 | 
					    implementation "lol.pyr:director-adventure:2.0.1"
 | 
				
			||||||
 | 
					    implementation project(":api")
 | 
				
			||||||
    compileOnly project(":api")
 | 
					 | 
				
			||||||
    compileOnly project(":folia")
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
shadowJar {
 | 
					shadowJar {
 | 
				
			||||||
 | 
					    archivesBaseName = "ZNPCsPlus"
 | 
				
			||||||
    archiveClassifier.set ""
 | 
					    archiveClassifier.set ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    relocate "org.bstats", "lol.pyr.znpcsplus.lib.bstats"
 | 
					    relocate "org.bstats", "lol.pyr.znpcsplus.lib.bstats"
 | 
				
			||||||
    relocate "org.apache.commons.io", "lol.pyr.znpcsplus.lib.commonsio"
 | 
					    relocate "org.apache.commons.io", "lol.pyr.znpcsplus.lib.commonsio"
 | 
				
			||||||
    relocate "me.robertlit.spigotresources", "lol.pyr.znpcsplus.lib.spigotresources"
 | 
					    relocate "me.robertlit.spigotresources", "lol.pyr.znpcsplus.lib.spigotresources"
 | 
				
			||||||
| 
						 | 
					@ -43,3 +53,5 @@ shadowJar {
 | 
				
			||||||
    relocate "lol.pyr.director", "lol.pyr.znpcsplus.lib.command"
 | 
					    relocate "lol.pyr.director", "lol.pyr.znpcsplus.lib.command"
 | 
				
			||||||
    minimize()
 | 
					    minimize()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tasks.assemble.dependsOn shadowJar
 | 
				
			||||||
| 
						 | 
					@ -15,6 +15,11 @@ public class ReflectionBuilder {
 | 
				
			||||||
    private Class<?> expectType;
 | 
					    private Class<?> expectType;
 | 
				
			||||||
    private boolean strict = true;
 | 
					    private boolean strict = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public ReflectionBuilder(Class<?> clazz) {
 | 
				
			||||||
 | 
					        this("");
 | 
				
			||||||
 | 
					        withClassName(clazz);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public ReflectionBuilder(String reflectionPackage) {
 | 
					    public ReflectionBuilder(String reflectionPackage) {
 | 
				
			||||||
        this(reflectionPackage, "", "", null);
 | 
					        this(reflectionPackage, "", "", null);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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.FieldReflection;
 | 
				
			||||||
import io.github.znetworkw.znpcservers.reflection.types.MethodReflection;
 | 
					import io.github.znetworkw.znpcservers.reflection.types.MethodReflection;
 | 
				
			||||||
import io.github.znetworkw.znpcservers.utility.Utils;
 | 
					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.lang.reflect.Method;
 | 
				
			||||||
 | 
					import java.util.concurrent.TimeUnit;
 | 
				
			||||||
import java.util.concurrent.atomic.AtomicInteger;
 | 
					import java.util.concurrent.atomic.AtomicInteger;
 | 
				
			||||||
 | 
					import java.util.function.Consumer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class containing all of the lazy-loaded reflections that the plugin
 | 
					 * Class containing all of the lazy-loaded reflections that the plugin
 | 
				
			||||||
 * uses to accessinaccessible things from the server jar.
 | 
					 * uses to accessinaccessible things from the server jar.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public final class Reflections {
 | 
					public final class Reflections {
 | 
				
			||||||
    public static final Class<?> ENTITY_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
					    public static final Class<?> ENTITY_CLASS = new ClassReflection(
 | 
				
			||||||
 | 
					            new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
				
			||||||
                    .withClassName("Entity")).get();
 | 
					                    .withClassName("Entity")).get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final Class<?> ENTITY_HUMAN_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
					    public static final Class<?> ENTITY_HUMAN_CLASS = new ClassReflection(
 | 
				
			||||||
 | 
					            new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
				
			||||||
                    .withSubClass("player")
 | 
					                    .withSubClass("player")
 | 
				
			||||||
                    .withClassName("EntityHuman")).get();
 | 
					                    .withClassName("EntityHuman")).get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final ReflectionLazyLoader<Method> GET_PROFILE_METHOD = new MethodReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
					    public static final ReflectionLazyLoader<Method> GET_PROFILE_METHOD = new MethodReflection(
 | 
				
			||||||
 | 
					            new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
				
			||||||
                    .withClassName(ENTITY_HUMAN_CLASS)
 | 
					                    .withClassName(ENTITY_HUMAN_CLASS)
 | 
				
			||||||
                    .withExpectResult(GameProfile.class));
 | 
					                    .withExpectResult(GameProfile.class));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final ReflectionLazyLoader<Method> GET_HANDLE_PLAYER_METHOD = new MethodReflection(new ReflectionBuilder(ReflectionPackage.BUKKIT)
 | 
					    public static final ReflectionLazyLoader<Method> GET_HANDLE_PLAYER_METHOD = new MethodReflection(
 | 
				
			||||||
 | 
					            new ReflectionBuilder(ReflectionPackage.BUKKIT)
 | 
				
			||||||
                    .withClassName("entity.CraftPlayer").withClassName("entity.CraftHumanEntity")
 | 
					                    .withClassName("entity.CraftPlayer").withClassName("entity.CraftHumanEntity")
 | 
				
			||||||
                    .withMethodName("getHandle"));
 | 
					                    .withMethodName("getHandle"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final FieldReflection.ValueModifier<Integer> ENTITY_ID_MODIFIER = new FieldReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
					    public static final FieldReflection.ValueModifier<Integer> ENTITY_ID_MODIFIER = new FieldReflection(
 | 
				
			||||||
 | 
					            new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
				
			||||||
                    .withClassName(ENTITY_CLASS)
 | 
					                    .withClassName(ENTITY_CLASS)
 | 
				
			||||||
                    .withFieldName("entityCount")
 | 
					                    .withFieldName("entityCount")
 | 
				
			||||||
                    .setStrict(!Utils.versionNewer(14))).staticValueModifier(int.class);
 | 
					                    .setStrict(!Utils.versionNewer(14))).staticValueModifier(int.class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final ReflectionLazyLoader<AtomicInteger> ATOMIC_ENTITY_ID_FIELD = new FieldReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
					    public static final ReflectionLazyLoader<AtomicInteger> ATOMIC_ENTITY_ID_FIELD = new FieldReflection(
 | 
				
			||||||
 | 
					            new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
				
			||||||
                    .withClassName(ENTITY_CLASS)
 | 
					                    .withClassName(ENTITY_CLASS)
 | 
				
			||||||
                    .withFieldName("entityCount")
 | 
					                    .withFieldName("entityCount")
 | 
				
			||||||
                    .withFieldName("d")
 | 
					                    .withFieldName("d")
 | 
				
			||||||
                    .withFieldName("c")
 | 
					                    .withFieldName("c")
 | 
				
			||||||
                    .withExpectResult(AtomicInteger.class)
 | 
					                    .withExpectResult(AtomicInteger.class)
 | 
				
			||||||
                    .setStrict(Utils.versionNewer(14))).staticValueLoader(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<Method> FOLIA_GET_ASYNC_SCHEDULER = new MethodReflection(
 | 
				
			||||||
 | 
					            new ReflectionBuilder(Bukkit.class)
 | 
				
			||||||
 | 
					                    .withMethodName("getAsyncScheduler")
 | 
				
			||||||
 | 
					                    .withExpectResult(ASYNC_SCHEDULER_CLASS)
 | 
				
			||||||
 | 
					                    .setStrict(FoliaUtil.isFolia()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static final ReflectionLazyLoader<Method> 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<Method> 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<Method> 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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,14 +1,14 @@
 | 
				
			||||||
package lol.pyr.znpcsplus.hologram;
 | 
					package lol.pyr.znpcsplus.hologram;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import lol.pyr.znpcsplus.config.Configs;
 | 
					import lol.pyr.znpcsplus.config.Configs;
 | 
				
			||||||
import lol.pyr.znpcsplus.util.ZLocation;
 | 
					 | 
				
			||||||
import lol.pyr.znpcsplus.util.Viewable;
 | 
					import lol.pyr.znpcsplus.util.Viewable;
 | 
				
			||||||
 | 
					import lol.pyr.znpcsplus.util.ZLocation;
 | 
				
			||||||
import net.kyori.adventure.text.Component;
 | 
					import net.kyori.adventure.text.Component;
 | 
				
			||||||
import org.bukkit.entity.Player;
 | 
					import org.bukkit.entity.Player;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.ArrayList;
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					import java.util.Collections;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
import java.util.Set;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class Hologram extends Viewable implements lol.pyr.znpcsplus.api.hologram.Hologram {
 | 
					public class Hologram extends Viewable implements lol.pyr.znpcsplus.api.hologram.Hologram {
 | 
				
			||||||
    private ZLocation location;
 | 
					    private ZLocation location;
 | 
				
			||||||
| 
						 | 
					@ -70,7 +70,7 @@ public class Hologram extends Viewable implements lol.pyr.znpcsplus.api.hologram
 | 
				
			||||||
        final double lineSpacing = Configs.config().lineSpacing();
 | 
					        final double lineSpacing = Configs.config().lineSpacing();
 | 
				
			||||||
        double height = location.getY() + lines.size() * lineSpacing;
 | 
					        double height = location.getY() + lines.size() * lineSpacing;
 | 
				
			||||||
        for (HologramLine line : lines) {
 | 
					        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;
 | 
					            height -= lineSpacing;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,7 +48,7 @@ public interface MetadataFactory {
 | 
				
			||||||
        throw new RuntimeException("Unsupported version!");
 | 
					        throw new RuntimeException("Unsupported version!");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private static Map<ServerVersion, LazyLoader<? extends MetadataFactory>> buildFactoryMap() {
 | 
					    static Map<ServerVersion, LazyLoader<? extends MetadataFactory>> buildFactoryMap() {
 | 
				
			||||||
        HashMap<ServerVersion, LazyLoader<? extends MetadataFactory>> map = new HashMap<>();
 | 
					        HashMap<ServerVersion, LazyLoader<? extends MetadataFactory>> map = new HashMap<>();
 | 
				
			||||||
        map.put(ServerVersion.V_1_8, LazyLoader.of(V1_8Factory::new));
 | 
					        map.put(ServerVersion.V_1_8, LazyLoader.of(V1_8Factory::new));
 | 
				
			||||||
        map.put(ServerVersion.V_1_9, LazyLoader.of(V1_9Factory::new));
 | 
					        map.put(ServerVersion.V_1_9, LazyLoader.of(V1_9Factory::new));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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.EntityData;
 | 
				
			||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
 | 
					import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
 | 
				
			||||||
import com.github.retrooper.packetevents.util.adventure.AdventureSerializer;
 | 
					import com.github.retrooper.packetevents.util.adventure.AdventureSerializer;
 | 
				
			||||||
 | 
					import lol.pyr.znpcsplus.util.list.ListUtil;
 | 
				
			||||||
import net.kyori.adventure.text.Component;
 | 
					import net.kyori.adventure.text.Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.Collection;
 | 
					import java.util.Collection;
 | 
				
			||||||
import java.util.List;
 | 
					 | 
				
			||||||
import java.util.Optional;
 | 
					import java.util.Optional;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class V1_13Factory extends V1_9Factory {
 | 
					public class V1_13Factory extends V1_9Factory {
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public Collection<EntityData> name(Component name) {
 | 
					    public Collection<EntityData> name(Component name) {
 | 
				
			||||||
        return List.of(
 | 
					        return ListUtil.immutableList(
 | 
				
			||||||
                new EntityData(2, EntityDataTypes.OPTIONAL_COMPONENT, Optional.of(AdventureSerializer.getGsonSerializer().serialize(name))),
 | 
					                new EntityData(2, EntityDataTypes.OPTIONAL_COMPONENT, Optional.of(AdventureSerializer.getGsonSerializer().serialize(name))),
 | 
				
			||||||
                new EntityData(3, EntityDataTypes.BOOLEAN, true)
 | 
					                new EntityData(3, EntityDataTypes.BOOLEAN, true)
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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.EntityData;
 | 
				
			||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
 | 
					import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
 | 
				
			||||||
import com.github.retrooper.packetevents.util.adventure.AdventureSerializer;
 | 
					import com.github.retrooper.packetevents.util.adventure.AdventureSerializer;
 | 
				
			||||||
 | 
					import lol.pyr.znpcsplus.util.list.ListUtil;
 | 
				
			||||||
import net.kyori.adventure.text.Component;
 | 
					import net.kyori.adventure.text.Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.Collection;
 | 
					import java.util.Collection;
 | 
				
			||||||
import java.util.List;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class V1_8Factory implements MetadataFactory {
 | 
					public class V1_8Factory implements MetadataFactory {
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
| 
						 | 
					@ -21,7 +21,7 @@ public class V1_8Factory implements MetadataFactory {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public Collection<EntityData> name(Component name) {
 | 
					    public Collection<EntityData> name(Component name) {
 | 
				
			||||||
        return List.of(
 | 
					        return ListUtil.immutableList(
 | 
				
			||||||
                new EntityData(2, EntityDataTypes.STRING, AdventureSerializer.getGsonSerializer().serialize(name)),
 | 
					                new EntityData(2, EntityDataTypes.STRING, AdventureSerializer.getGsonSerializer().serialize(name)),
 | 
				
			||||||
                new EntityData(3, EntityDataTypes.BYTE, 1)
 | 
					                new EntityData(3, EntityDataTypes.BYTE, 1)
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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.EntityData;
 | 
				
			||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
 | 
					import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
 | 
				
			||||||
import com.github.retrooper.packetevents.util.adventure.AdventureSerializer;
 | 
					import com.github.retrooper.packetevents.util.adventure.AdventureSerializer;
 | 
				
			||||||
 | 
					import lol.pyr.znpcsplus.util.list.ListUtil;
 | 
				
			||||||
import net.kyori.adventure.text.Component;
 | 
					import net.kyori.adventure.text.Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.Collection;
 | 
					import java.util.Collection;
 | 
				
			||||||
import java.util.List;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class V1_9Factory extends V1_8Factory {
 | 
					public class V1_9Factory extends V1_8Factory {
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
| 
						 | 
					@ -21,7 +21,7 @@ public class V1_9Factory extends V1_8Factory {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public Collection<EntityData> name(Component name) {
 | 
					    public Collection<EntityData> name(Component name) {
 | 
				
			||||||
        return List.of(
 | 
					        return ListUtil.immutableList(
 | 
				
			||||||
                new EntityData(2, EntityDataTypes.STRING, AdventureSerializer.getGsonSerializer().serialize(name)),
 | 
					                new EntityData(2, EntityDataTypes.STRING, AdventureSerializer.getGsonSerializer().serialize(name)),
 | 
				
			||||||
                new EntityData(3, EntityDataTypes.BOOLEAN, true)
 | 
					                new EntityData(3, EntityDataTypes.BOOLEAN, true)
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,7 +43,7 @@ public interface PacketFactory {
 | 
				
			||||||
        throw new RuntimeException("Unsupported version!");
 | 
					        throw new RuntimeException("Unsupported version!");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private static Map<ServerVersion, LazyLoader<? extends PacketFactory>> buildFactoryMap() {
 | 
					    static Map<ServerVersion, LazyLoader<? extends PacketFactory>> buildFactoryMap() {
 | 
				
			||||||
        HashMap<ServerVersion, LazyLoader<? extends PacketFactory>> map = new HashMap<>();
 | 
					        HashMap<ServerVersion, LazyLoader<? extends PacketFactory>> map = new HashMap<>();
 | 
				
			||||||
        map.put(ServerVersion.V_1_8, LazyLoader.of(V1_8Factory::new));
 | 
					        map.put(ServerVersion.V_1_8, LazyLoader.of(V1_8Factory::new));
 | 
				
			||||||
        map.put(ServerVersion.V_1_9, LazyLoader.of(V1_9Factory::new));
 | 
					        map.put(ServerVersion.V_1_9, LazyLoader.of(V1_9Factory::new));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,6 +22,7 @@ import net.kyori.adventure.text.format.NamedTextColor;
 | 
				
			||||||
import org.bukkit.entity.Player;
 | 
					import org.bukkit.entity.Player;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.ArrayList;
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					import java.util.Collections;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
import java.util.Optional;
 | 
					import java.util.Optional;
 | 
				
			||||||
import java.util.concurrent.CompletableFuture;
 | 
					import java.util.concurrent.CompletableFuture;
 | 
				
			||||||
| 
						 | 
					@ -33,7 +34,7 @@ public class V1_8Factory implements PacketFactory {
 | 
				
			||||||
            createTeam(player, entity, properties);
 | 
					            createTeam(player, entity, properties);
 | 
				
			||||||
            ZLocation location = entity.getLocation();
 | 
					            ZLocation location = entity.getLocation();
 | 
				
			||||||
            sendPacket(player, new WrapperPlayServerSpawnPlayer(entity.getEntityId(),
 | 
					            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);
 | 
					            sendAllMetadata(player, entity, properties);
 | 
				
			||||||
            ZNPCsPlus.SCHEDULER.runLaterAsync(() -> removeTabPlayer(player, entity), 60);
 | 
					            ZNPCsPlus.SCHEDULER.runLaterAsync(() -> removeTabPlayer(player, entity), 60);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
| 
						 | 
					@ -46,7 +47,7 @@ public class V1_8Factory implements PacketFactory {
 | 
				
			||||||
        ClientVersion clientVersion = PacketEvents.getAPI().getServerManager().getVersion().toClientVersion();
 | 
					        ClientVersion clientVersion = PacketEvents.getAPI().getServerManager().getVersion().toClientVersion();
 | 
				
			||||||
        sendPacket(player, type.getLegacyId(clientVersion) == -1 ?
 | 
					        sendPacket(player, type.getLegacyId(clientVersion) == -1 ?
 | 
				
			||||||
                new WrapperPlayServerSpawnLivingEntity(entity.getEntityId(), entity.getUuid(), type, location.toVector3d(),
 | 
					                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(),
 | 
					                new WrapperPlayServerSpawnEntity(entity.getEntityId(), Optional.of(entity.getUuid()), entity.getType(), location.toVector3d(),
 | 
				
			||||||
                        location.getPitch(), location.getYaw(), location.getYaw(), 0, Optional.empty()));
 | 
					                        location.getPitch(), location.getYaw(), location.getYaw(), 0, Optional.empty()));
 | 
				
			||||||
        sendAllMetadata(player, entity, properties);
 | 
					        sendAllMetadata(player, entity, properties);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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<Object>) 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<Object>) 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<Object>) 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);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,9 +5,11 @@ import com.github.retrooper.packetevents.protocol.player.UserProfile;
 | 
				
			||||||
import com.google.gson.JsonElement;
 | 
					import com.google.gson.JsonElement;
 | 
				
			||||||
import com.google.gson.JsonObject;
 | 
					import com.google.gson.JsonObject;
 | 
				
			||||||
import com.mojang.authlib.properties.PropertyMap;
 | 
					import com.mojang.authlib.properties.PropertyMap;
 | 
				
			||||||
 | 
					import lol.pyr.znpcsplus.util.list.ListUtil;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.ArrayList;
 | 
					import java.util.ArrayList;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					import java.util.stream.Collectors;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class Skin {
 | 
					public class Skin {
 | 
				
			||||||
    private final long timestamp = System.currentTimeMillis();
 | 
					    private final long timestamp = System.currentTimeMillis();
 | 
				
			||||||
| 
						 | 
					@ -18,13 +20,13 @@ public class Skin {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public Skin(TextureProperty... properties) {
 | 
					    public Skin(TextureProperty... properties) {
 | 
				
			||||||
        this.properties.addAll(List.of(properties));
 | 
					        this.properties.addAll(ListUtil.immutableList(properties));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public Skin(PropertyMap properties) {
 | 
					    public Skin(PropertyMap properties) {
 | 
				
			||||||
        this.properties.addAll(properties.values().stream()
 | 
					        this.properties.addAll(properties.values().stream()
 | 
				
			||||||
                .map(property -> new TextureProperty(property.getName(), property.getValue(), property.getSignature()))
 | 
					                .map(property -> new TextureProperty(property.getName(), property.getValue(), property.getSignature()))
 | 
				
			||||||
                .toList());
 | 
					                .collect(Collectors.toList()));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public Skin(JsonObject obj) {
 | 
					    public Skin(JsonObject obj) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,9 @@
 | 
				
			||||||
package lol.pyr.znpcsplus.util;
 | 
					package lol.pyr.znpcsplus.util;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class FoliaUtil {
 | 
					public class FoliaUtil {
 | 
				
			||||||
 | 
					    private static final Boolean FOLIA = isFolia();
 | 
				
			||||||
    public static boolean isFolia() {
 | 
					    public static boolean isFolia() {
 | 
				
			||||||
 | 
					        if (FOLIA != null) return FOLIA;
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            Class.forName("io.papermc.paper.threadedregions.RegionizedServer");
 | 
					            Class.forName("io.papermc.paper.threadedregions.RegionizedServer");
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,62 @@
 | 
				
			||||||
 | 
					package lol.pyr.znpcsplus.util.list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.Iterator;
 | 
				
			||||||
 | 
					import java.util.ListIterator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class ArrayIterator<T> implements Iterator<T>, ListIterator<T> {
 | 
				
			||||||
 | 
					    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();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,133 @@
 | 
				
			||||||
 | 
					package lol.pyr.znpcsplus.util.list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class ImmutableArrayList<T> implements List<T> {
 | 
				
			||||||
 | 
					    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<T> iterator() {
 | 
				
			||||||
 | 
					        return new ArrayIterator<>(elements);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public Object[] toArray() {
 | 
				
			||||||
 | 
					        return elements;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @SuppressWarnings("unchecked")
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public <T1> 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<T> 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<T> listIterator() {
 | 
				
			||||||
 | 
					        return new ArrayIterator<>(elements);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public ListIterator<T> 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<? extends T> c) {
 | 
				
			||||||
 | 
					        throw new UnsupportedOperationException();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public boolean addAll(int index, Collection<? extends T> 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();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,10 @@
 | 
				
			||||||
 | 
					package lol.pyr.znpcsplus.util.list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class ListUtil {
 | 
				
			||||||
 | 
					    @SafeVarargs
 | 
				
			||||||
 | 
					    public static <T> List<T> immutableList(T... elements) {
 | 
				
			||||||
 | 
					        return new ImmutableArrayList<>(elements);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in a new issue