From 30cca1c5e5b58c6ad3c3c90089faec458ac0db5c Mon Sep 17 00:00:00 2001 From: Ankoki-Dev Date: Thu, 3 Feb 2022 15:07:25 +0000 Subject: [PATCH] 1.4 release ^-^ --- pom.xml | 28 +- src/main/java/com/ankoki/skjade/SkJade.java | 17 +- .../elements/conditions/CondBoolean.java | 2 +- .../elements/conditions/CondCanBreak.java | 2 +- .../elements/conditions/CondCanSee.java | 2 +- .../elements/conditions/CondLocIsWithin.java | 2 +- .../elements/conditions/CondMultiple.java | 2 +- .../skjade/elements/effects/EffDropTool.java | 2 +- .../skjade/elements/effects/EffEvaluate.java | 2 +- .../elements/effects/EffFakeDamage.java | 2 +- .../elements/effects/EffForceSleep.java | 2 +- .../skjade/elements/effects/EffForceWake.java | 2 +- .../elements/effects/EffRefreshChunks.java | 2 +- .../skjade/elements/effects/EffShowDemo.java | 2 +- .../elements/events/EvtAsyncPreLogin.java | 2 +- .../elements/expressions/ExprBorderSlots.java | 2 +- .../elements/expressions/ExprChunkAt.java | 2 +- .../elements/expressions/ExprCircle.java | 2 +- .../expressions/ExprEnglishPlural.java | 2 +- .../elements/expressions/ExprFlippedBool.java | 2 +- .../elements/expressions/ExprMidnight.java | 2 +- .../expressions/ExprNearestEntity.java | 2 +- .../elements/expressions/ExprProgressBar.java | 2 +- .../expressions/ExprRomanNumerals.java | 2 +- .../skjade/elements/expressions/ExprStar.java | 2 +- .../expressions/ExprTimeAtPlayer.java | 2 +- .../ankoki/skjade/elements/lasers/Laser.java | 1034 +++++++++++++---- .../lasers/effects/EffAttachEndEntity.java | 57 + .../lasers/effects/EffChangeLaserColour.java | 6 +- .../lasers/effects/EffCreateLaser.java | 6 +- .../elements/lasers/effects/EffShowLaser.java | 5 +- .../lasers/effects/EffStartLaser.java | 3 +- .../elements/lasers/effects/EffStopLaser.java | 4 +- .../lasers/expressions/ExprLaser.java | 4 +- .../lasers/expressions/ExprLaserPoints.java | 4 +- .../skjade/hooks/elementals/EleClassInfo.java | 1 - .../conditions/CondCanCastSpell.java | 2 +- .../conditions/CondSpellExists.java | 2 +- .../elementals/conditions/CondSpellType.java | 2 +- .../elementals/effects/EffCreateSpell.java | 2 +- .../elementals/effects/EffEnchantItem.java | 2 +- .../elementals/events/EvtSpellCancel.java | 2 +- .../hooks/elementals/events/EvtSpellCast.java | 2 +- .../elementals/expressions/ExprSpell.java | 2 +- .../elementals/expressions/ExprSpellBook.java | 2 +- .../elementals/expressions/ExprSpellID.java | 2 +- .../skjade/hooks/holograms/HoloClassInfo.java | 12 +- .../conditions/CondHasInteractionHandler.java | 2 +- .../holograms/conditions/CondIsHologram.java | 2 +- .../holograms/effects/EffAddItemLine.java | 2 +- .../holograms/effects/EffAddTextLine.java | 2 +- .../holograms/effects/EffCreateHolo.java | 2 +- .../holograms/effects/EffDeleteHolo.java | 2 +- .../effects/EffInteractableLine.java | 2 +- .../effects/EffRegisterPlaceholder.java | 2 +- .../holograms/effects/EffRemoveLine.java | 2 +- .../holograms/effects/EffResetVisibility.java | 2 +- .../holograms/effects/EffSetVisibility.java | 2 +- .../effects/EffUnregisterPlaceholder.java | 2 +- .../events/EvtHologramLineClick.java | 2 +- .../events/EvtHologramLineTouch.java | 2 +- .../holograms/expressions/ExprHologram.java | 2 +- .../expressions/ExprHologramLine.java | 2 +- .../protocollib/effects/EffRotatePlayer.java | 2 +- .../skjade/utils/NonLegacyClassInfo.java | 1 - .../java/com/ankoki/skjade/utils/Version.java | 78 +- 66 files changed, 976 insertions(+), 386 deletions(-) create mode 100644 src/main/java/com/ankoki/skjade/elements/lasers/effects/EffAttachEndEntity.java diff --git a/pom.xml b/pom.xml index ca0f338..3be8803 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.ankoki SkJade - 1.3.4 + 1.4 1.8 @@ -54,6 +54,11 @@ + + skript-releases + Skript Repository + https://repo.skriptlang.org/releases + jitpack.io https://jitpack.io @@ -88,26 +93,7 @@ com.github.SkriptLang Skript - 2.6-alpha1 - provided - - - com.sk89q - worldguard - - - com.sk89q.worldguard - worldguard-legacy - - - com.github.marcelo-mason - PreciousStones - - - net.milkbowl.vault - Vault - - + 2.6.1 com.github.Ankoki-Dev diff --git a/src/main/java/com/ankoki/skjade/SkJade.java b/src/main/java/com/ankoki/skjade/SkJade.java index daf57a1..cf4a1d5 100644 --- a/src/main/java/com/ankoki/skjade/SkJade.java +++ b/src/main/java/com/ankoki/skjade/SkJade.java @@ -37,7 +37,6 @@ public class SkJade extends JavaPlugin { private boolean beta; private static SkJade instance; private String version; - private Version serverVersion; private PluginManager pluginManager; private SkriptAddon addon; private boolean nmsEnabled = false; @@ -94,7 +93,6 @@ public void onEnable() { } new Metrics(this, 10131); this.getServer().getPluginCommand("skjade").setExecutor(new SkJadeCmd()); - this.loadServerVersion(); this.startRealTime(); long fin = System.currentTimeMillis() - start; @@ -112,7 +110,7 @@ public void onEnable() { }).start(); } - if (serverVersion.isLegacy()) { + if (Version.currentIsLegacy()) { Console.warning("Please note SkJade does not support legacy versions. The supported versions are 1.13+."); Console.warning("You have no reason to not use the latest server version. SkJade will still be enabled, " + "however you may encounter some issues which may not get fixed due to not supporting fossil versions."); @@ -120,9 +118,10 @@ public void onEnable() { } private void loadNMS() { - if (Utils.getServerMajorVersion() < 13) { + if (Version.currentIsLegacy() || Version.CURRENT_VERSION == Version.UNKNOWN) { Console.warning("Could not find any NMS support for " + version + "! Please note SkJade only supports " + "the latest sub-version of each version above 1.13."); + Console.warning("There is also a chance you are using a version I haven't implemented support for yet."); Console.info("SkJade will remain enabled, however anything using NMS will not be enabled!"); } else { nmsEnabled = true; @@ -166,16 +165,6 @@ private void loadHDElements() { } } - private void loadServerVersion() { - String packageName = this.getServer().getClass().getPackage().getName(); - String ver = packageName.substring(packageName.lastIndexOf('.') + 1); - try { - serverVersion = Version.valueOf(ver); - } catch (Exception ex) { - Console.warning("You are using an unknown version (" + ver + ")! SkJade will not function as intended"); - } - } - private void loadElementalsElements() { try { addon.loadClasses("com.ankoki.skjade.hooks.elementals"); diff --git a/src/main/java/com/ankoki/skjade/elements/conditions/CondBoolean.java b/src/main/java/com/ankoki/skjade/elements/conditions/CondBoolean.java index e9ff1b5..ed7aefb 100644 --- a/src/main/java/com/ankoki/skjade/elements/conditions/CondBoolean.java +++ b/src/main/java/com/ankoki/skjade/elements/conditions/CondBoolean.java @@ -10,7 +10,7 @@ import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.util.Kleenean; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Boolean") @Description("Shortens statements such as true = true to just true.") diff --git a/src/main/java/com/ankoki/skjade/elements/conditions/CondCanBreak.java b/src/main/java/com/ankoki/skjade/elements/conditions/CondCanBreak.java index 87d179f..ebb638e 100644 --- a/src/main/java/com/ankoki/skjade/elements/conditions/CondCanBreak.java +++ b/src/main/java/com/ankoki/skjade/elements/conditions/CondCanBreak.java @@ -9,7 +9,7 @@ import ch.njol.util.Kleenean; import org.bukkit.block.Block; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Can Break Block") @Description("Checks if an item type can break a block.") diff --git a/src/main/java/com/ankoki/skjade/elements/conditions/CondCanSee.java b/src/main/java/com/ankoki/skjade/elements/conditions/CondCanSee.java index ae34176..20943fe 100644 --- a/src/main/java/com/ankoki/skjade/elements/conditions/CondCanSee.java +++ b/src/main/java/com/ankoki/skjade/elements/conditions/CondCanSee.java @@ -12,7 +12,7 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Can See") @Description("Checks if a living entity can see another living entity.") diff --git a/src/main/java/com/ankoki/skjade/elements/conditions/CondLocIsWithin.java b/src/main/java/com/ankoki/skjade/elements/conditions/CondLocIsWithin.java index f783db2..a4e98a6 100644 --- a/src/main/java/com/ankoki/skjade/elements/conditions/CondLocIsWithin.java +++ b/src/main/java/com/ankoki/skjade/elements/conditions/CondLocIsWithin.java @@ -11,7 +11,7 @@ import ch.njol.util.Kleenean; import org.bukkit.Location; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Location is Within") @Description("Checks if a location is between two locations") diff --git a/src/main/java/com/ankoki/skjade/elements/conditions/CondMultiple.java b/src/main/java/com/ankoki/skjade/elements/conditions/CondMultiple.java index e900cf8..1d3ee6c 100644 --- a/src/main/java/com/ankoki/skjade/elements/conditions/CondMultiple.java +++ b/src/main/java/com/ankoki/skjade/elements/conditions/CondMultiple.java @@ -10,7 +10,7 @@ import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.util.Kleenean; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Multiple Conditions") @Description("Allows you to use multiple conditions.") diff --git a/src/main/java/com/ankoki/skjade/elements/effects/EffDropTool.java b/src/main/java/com/ankoki/skjade/elements/effects/EffDropTool.java index 49fa215..3293b29 100644 --- a/src/main/java/com/ankoki/skjade/elements/effects/EffDropTool.java +++ b/src/main/java/com/ankoki/skjade/elements/effects/EffDropTool.java @@ -11,7 +11,7 @@ import ch.njol.util.Kleenean; import org.bukkit.entity.Player; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Drop Item") @Description("Makes the player drop one of their current item, or their inventory.") diff --git a/src/main/java/com/ankoki/skjade/elements/effects/EffEvaluate.java b/src/main/java/com/ankoki/skjade/elements/effects/EffEvaluate.java index 09b8fac..4ba6632 100644 --- a/src/main/java/com/ankoki/skjade/elements/effects/EffEvaluate.java +++ b/src/main/java/com/ankoki/skjade/elements/effects/EffEvaluate.java @@ -11,7 +11,7 @@ import ch.njol.skript.lang.TriggerItem; import ch.njol.util.Kleenean; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; import java.util.Arrays; diff --git a/src/main/java/com/ankoki/skjade/elements/effects/EffFakeDamage.java b/src/main/java/com/ankoki/skjade/elements/effects/EffFakeDamage.java index 9155c38..a72e423 100644 --- a/src/main/java/com/ankoki/skjade/elements/effects/EffFakeDamage.java +++ b/src/main/java/com/ankoki/skjade/elements/effects/EffFakeDamage.java @@ -14,7 +14,7 @@ import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Fake Damage") @Description("Makes a player look like they took damage.") diff --git a/src/main/java/com/ankoki/skjade/elements/effects/EffForceSleep.java b/src/main/java/com/ankoki/skjade/elements/effects/EffForceSleep.java index 66006c4..2fcf347 100644 --- a/src/main/java/com/ankoki/skjade/elements/effects/EffForceSleep.java +++ b/src/main/java/com/ankoki/skjade/elements/effects/EffForceSleep.java @@ -12,7 +12,7 @@ import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; import java.util.Arrays; diff --git a/src/main/java/com/ankoki/skjade/elements/effects/EffForceWake.java b/src/main/java/com/ankoki/skjade/elements/effects/EffForceWake.java index f462db1..a699e87 100644 --- a/src/main/java/com/ankoki/skjade/elements/effects/EffForceWake.java +++ b/src/main/java/com/ankoki/skjade/elements/effects/EffForceWake.java @@ -11,7 +11,7 @@ import ch.njol.util.Kleenean; import org.bukkit.entity.Player; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; import java.util.Arrays; diff --git a/src/main/java/com/ankoki/skjade/elements/effects/EffRefreshChunks.java b/src/main/java/com/ankoki/skjade/elements/effects/EffRefreshChunks.java index cbb815c..f1de87d 100644 --- a/src/main/java/com/ankoki/skjade/elements/effects/EffRefreshChunks.java +++ b/src/main/java/com/ankoki/skjade/elements/effects/EffRefreshChunks.java @@ -11,7 +11,7 @@ import ch.njol.util.Kleenean; import org.bukkit.Chunk; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; import java.util.Arrays; diff --git a/src/main/java/com/ankoki/skjade/elements/effects/EffShowDemo.java b/src/main/java/com/ankoki/skjade/elements/effects/EffShowDemo.java index b228f39..1e31d4e 100644 --- a/src/main/java/com/ankoki/skjade/elements/effects/EffShowDemo.java +++ b/src/main/java/com/ankoki/skjade/elements/effects/EffShowDemo.java @@ -15,7 +15,7 @@ import com.ankoki.skjade.utils.Utils; import org.bukkit.entity.Player; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Show Demo") @Description("Shows the minecraft demonstration screen to a player.") diff --git a/src/main/java/com/ankoki/skjade/elements/events/EvtAsyncPreLogin.java b/src/main/java/com/ankoki/skjade/elements/events/EvtAsyncPreLogin.java index 5835872..2439556 100644 --- a/src/main/java/com/ankoki/skjade/elements/events/EvtAsyncPreLogin.java +++ b/src/main/java/com/ankoki/skjade/elements/events/EvtAsyncPreLogin.java @@ -10,7 +10,7 @@ import ch.njol.skript.util.Getter; import org.bukkit.event.Event; import org.bukkit.event.player.AsyncPlayerPreLoginEvent; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; import java.util.UUID; diff --git a/src/main/java/com/ankoki/skjade/elements/expressions/ExprBorderSlots.java b/src/main/java/com/ankoki/skjade/elements/expressions/ExprBorderSlots.java index 6e95f04..c6055a6 100644 --- a/src/main/java/com/ankoki/skjade/elements/expressions/ExprBorderSlots.java +++ b/src/main/java/com/ankoki/skjade/elements/expressions/ExprBorderSlots.java @@ -17,7 +17,7 @@ import org.bukkit.event.inventory.InventoryType; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/com/ankoki/skjade/elements/expressions/ExprChunkAt.java b/src/main/java/com/ankoki/skjade/elements/expressions/ExprChunkAt.java index 712a130..632848b 100644 --- a/src/main/java/com/ankoki/skjade/elements/expressions/ExprChunkAt.java +++ b/src/main/java/com/ankoki/skjade/elements/expressions/ExprChunkAt.java @@ -13,7 +13,7 @@ import org.bukkit.Chunk; import org.bukkit.World; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Chunk at Location") @Description("Returns the chunk in a world from the x and y coordinates.") diff --git a/src/main/java/com/ankoki/skjade/elements/expressions/ExprCircle.java b/src/main/java/com/ankoki/skjade/elements/expressions/ExprCircle.java index cc08e91..f05af47 100644 --- a/src/main/java/com/ankoki/skjade/elements/expressions/ExprCircle.java +++ b/src/main/java/com/ankoki/skjade/elements/expressions/ExprCircle.java @@ -13,7 +13,7 @@ import com.ankoki.skjade.utils.Shapes; import org.bukkit.Location; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Circle") @Description("Returns the points of the outline of a circle which ") diff --git a/src/main/java/com/ankoki/skjade/elements/expressions/ExprEnglishPlural.java b/src/main/java/com/ankoki/skjade/elements/expressions/ExprEnglishPlural.java index abccff2..7576255 100644 --- a/src/main/java/com/ankoki/skjade/elements/expressions/ExprEnglishPlural.java +++ b/src/main/java/com/ankoki/skjade/elements/expressions/ExprEnglishPlural.java @@ -8,7 +8,7 @@ import ch.njol.skript.expressions.base.SimplePropertyExpression; import ch.njol.skript.lang.ExpressionType; import ch.njol.skript.util.Utils; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("English Plural") @Description("Returns the english plural of a word. This may be inaccurate.") diff --git a/src/main/java/com/ankoki/skjade/elements/expressions/ExprFlippedBool.java b/src/main/java/com/ankoki/skjade/elements/expressions/ExprFlippedBool.java index aab6777..7d29ee2 100644 --- a/src/main/java/com/ankoki/skjade/elements/expressions/ExprFlippedBool.java +++ b/src/main/java/com/ankoki/skjade/elements/expressions/ExprFlippedBool.java @@ -11,7 +11,7 @@ import ch.njol.skript.lang.util.SimpleExpression; import ch.njol.util.Kleenean; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Flipped Boolean") @Description("Returns the flipped value of a boolean") diff --git a/src/main/java/com/ankoki/skjade/elements/expressions/ExprMidnight.java b/src/main/java/com/ankoki/skjade/elements/expressions/ExprMidnight.java index 0169325..dc9d2c1 100644 --- a/src/main/java/com/ankoki/skjade/elements/expressions/ExprMidnight.java +++ b/src/main/java/com/ankoki/skjade/elements/expressions/ExprMidnight.java @@ -12,7 +12,7 @@ import ch.njol.skript.util.Date; import ch.njol.util.Kleenean; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Midnight") @Description("Returns the date of midnight.") diff --git a/src/main/java/com/ankoki/skjade/elements/expressions/ExprNearestEntity.java b/src/main/java/com/ankoki/skjade/elements/expressions/ExprNearestEntity.java index a1c16c4..cceda59 100644 --- a/src/main/java/com/ankoki/skjade/elements/expressions/ExprNearestEntity.java +++ b/src/main/java/com/ankoki/skjade/elements/expressions/ExprNearestEntity.java @@ -15,7 +15,7 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Nearest Entity") @Description("Returns the nearest entity to a location.") diff --git a/src/main/java/com/ankoki/skjade/elements/expressions/ExprProgressBar.java b/src/main/java/com/ankoki/skjade/elements/expressions/ExprProgressBar.java index 2719af4..2501bc4 100644 --- a/src/main/java/com/ankoki/skjade/elements/expressions/ExprProgressBar.java +++ b/src/main/java/com/ankoki/skjade/elements/expressions/ExprProgressBar.java @@ -6,7 +6,7 @@ import ch.njol.util.Kleenean; import net.md_5.bungee.api.ChatColor; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; import java.awt.*; diff --git a/src/main/java/com/ankoki/skjade/elements/expressions/ExprRomanNumerals.java b/src/main/java/com/ankoki/skjade/elements/expressions/ExprRomanNumerals.java index e2ac7e5..19bab1a 100644 --- a/src/main/java/com/ankoki/skjade/elements/expressions/ExprRomanNumerals.java +++ b/src/main/java/com/ankoki/skjade/elements/expressions/ExprRomanNumerals.java @@ -12,7 +12,7 @@ import ch.njol.util.Kleenean; import com.ankoki.skjade.utils.Utils; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Roman Numerals") @Description("Returns the given number in roman numerals.") diff --git a/src/main/java/com/ankoki/skjade/elements/expressions/ExprStar.java b/src/main/java/com/ankoki/skjade/elements/expressions/ExprStar.java index be3523e..b470f00 100644 --- a/src/main/java/com/ankoki/skjade/elements/expressions/ExprStar.java +++ b/src/main/java/com/ankoki/skjade/elements/expressions/ExprStar.java @@ -13,7 +13,7 @@ import com.ankoki.skjade.utils.Shapes; import org.bukkit.Location; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Star") @Description("Returns the points of the outline of a star from the center, radius, and density") diff --git a/src/main/java/com/ankoki/skjade/elements/expressions/ExprTimeAtPlayer.java b/src/main/java/com/ankoki/skjade/elements/expressions/ExprTimeAtPlayer.java index e487bd6..d773100 100644 --- a/src/main/java/com/ankoki/skjade/elements/expressions/ExprTimeAtPlayer.java +++ b/src/main/java/com/ankoki/skjade/elements/expressions/ExprTimeAtPlayer.java @@ -16,7 +16,7 @@ import ch.njol.util.coll.CollectionUtils; import org.bukkit.entity.Player; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Time at Player") @Description("Returns the player's time.") diff --git a/src/main/java/com/ankoki/skjade/elements/lasers/Laser.java b/src/main/java/com/ankoki/skjade/elements/lasers/Laser.java index f47e13c..94e4b36 100644 --- a/src/main/java/com/ankoki/skjade/elements/lasers/Laser.java +++ b/src/main/java/com/ankoki/skjade/elements/lasers/Laser.java @@ -4,15 +4,27 @@ import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; +import com.ankoki.skjade.SkJade; import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; import org.bukkit.scheduler.BukkitRunnable; @@ -26,106 +38,92 @@ * @author SkytAsul * @see GitHub page */ -public class Laser { - private static int teamID = ThreadLocalRandom.current().nextInt(0, Integer.MAX_VALUE); - - private final int duration; - private final int distanceSquared; - private Location start; - private Location end; - - private final Object createGuardianPacket; - private final Object createSquidPacket; - private final Object teamCreatePacket; - private final Object[] destroyPackets; - private final Object metadataPacketGuardian; - private final Object metadataPacketSquid; - private final Object fakeGuardianDataWatcher; - - private final Object squid; - private final int squidID; - private final UUID squidUUID; - private final Object guardian; - private final int guardianID; - private final UUID guardianUUID; - - private Plugin plugin; - private BukkitRunnable main; - private BukkitTask startMove, endMove; - private HashSet show = new HashSet<>(); +public abstract class Laser { - /** - * Create a Laser instance - * - * @param start Location where laser will starts - * @param end Location where laser will ends - * @param duration Duration of laser in seconds (-1 if infinite) - * @param distance Distance where laser will be visible - */ - public Laser(Location start, Location end, int duration, int distance) throws ReflectiveOperationException { - if (!Packets.enabled) - throw new IllegalStateException("The Laser Beam API is disabled. An error has occured during initialization."); + protected final int distanceSquared; + protected final int duration; + protected boolean durationInTicks = false; + protected Location start; + protected Location end; + + protected Plugin plugin; + protected BukkitRunnable main; + + protected BukkitTask startMove; + protected BukkitTask endMove; + + protected Set show = ConcurrentHashMap.newKeySet(); + private Set seen = new HashSet<>(); + + private List executeEnd = new ArrayList<>(1); + + protected Laser(Location start, Location end, int duration, int distance) { + if (!Packets.enabled) throw new IllegalStateException("The Laser Beam API is disabled. An error has occured during initialization."); + if (start.getWorld() != end.getWorld()) throw new IllegalArgumentException("Locations do not belong to the same worlds."); this.start = start; this.end = end; this.duration = duration; - distanceSquared = distance * distance; - - if (Packets.version < 17) { - squid = null; - createSquidPacket = Packets.createPacketSquidSpawn(end); - } else { - squid = Packets.createSquid(end); - createSquidPacket = Packets.createPacketEntitySpawn(squid); - } - squidID = (int) Packets.getField(createSquidPacket, "a"); - squidUUID = (UUID) Packets.getField(createSquidPacket, "b"); - metadataPacketSquid = Packets.createPacketMetadata(squidID, Packets.fakeSquidWatcher); - Packets.setDirtyWatcher(Packets.fakeSquidWatcher); - - fakeGuardianDataWatcher = Packets.createFakeDataWatcher(); - Packets.initGuardianWatcher(fakeGuardianDataWatcher, squidID); - if (Packets.version < 17) { - guardian = null; - createGuardianPacket = Packets.createPacketGuardianSpawn(start, fakeGuardianDataWatcher, squidID); - } else { - guardian = Packets.createGuardian(start); - createGuardianPacket = Packets.createPacketEntitySpawn(guardian); - } - guardianID = (int) Packets.getField(createGuardianPacket, "a"); - guardianUUID = (UUID) Packets.getField(createGuardianPacket, "b"); - metadataPacketGuardian = Packets.createPacketMetadata(guardianID, fakeGuardianDataWatcher); - - teamCreatePacket = Packets.createPacketTeamCreate("noclip" + teamID++, squidUUID, guardianUUID); - destroyPackets = Packets.createPacketsRemoveEntities(squidID, guardianID); + distanceSquared = distance < 0 ? -1 : distance * distance; } + /** + * Adds a runnable to execute when the laser reaches its final duration + * @param runnable action to execute + * @return this {@link Laser} instance + */ + public Laser executeEnd(Runnable runnable) { + executeEnd.add(runnable); + return this; + } + + /** + * Makes the duration provided in the constructor passed as ticks and not seconds + * @return this {@link Laser} instance + */ + public Laser durationInTicks() { + durationInTicks = true; + return this; + } + + public void start(Plugin plugin) { + this.start(plugin, start.getWorld().getPlayers().toArray(new Player[0])); + } + + /** + * Starts this laser. + *

+ * It will make the laser visible for nearby players and start the countdown to the final duration. + *

+ * Once finished, it will destroy the laser and execute all runnables passed with {@link Laser#executeEnd}. + * @param plugin plugin used to start the task + */ public void start(Plugin plugin, Player[] players) { - this.plugin = plugin; Validate.isTrue(main == null, "Task already started"); + this.plugin = plugin; main = new BukkitRunnable() { - int time = duration; + int time = 0; @Override public void run() { try { - if (time == 0) { + if (time == duration) { cancel(); return; } - for (Player p : players) { - if (p.getWorld() != start.getWorld()) continue; - if (isCloseEnough(p.getLocation())) { - if (!show.contains(p)) { - sendStartPackets(p); - show.add(p); + if (!durationInTicks || time % 20 == 0) { + for (Player p : players) { + if (start.getWorld() != p.getWorld()) continue; + if (isCloseEnough(p)) { + if (show.add(p)) { + sendStartPackets(p, !seen.add(p)); + } + }else if (show.remove(p)) { + sendDestroyPackets(p); } - } else if (show.contains(p)) { - Packets.sendPackets(p, destroyPackets); - show.remove(p); } } - if (time != -1) time--; - } catch (ReflectiveOperationException e) { + time++; + }catch (ReflectiveOperationException e) { e.printStackTrace(); } } @@ -133,52 +131,99 @@ public void run() { @Override public synchronized void cancel() throws IllegalStateException { super.cancel(); + main = null; try { for (Player p : show) { - Packets.sendPackets(p, destroyPackets); + sendDestroyPackets(p); } - } catch (ReflectiveOperationException e) { + show.clear(); + executeEnd.forEach(Runnable::run); + }catch (ReflectiveOperationException e) { e.printStackTrace(); } - main = null; } }; - main.runTaskTimerAsynchronously(plugin, 0L, 20L); + main.runTaskTimerAsynchronously(plugin, 0L, durationInTicks ? 1L : 20L); } + /** + * Stops this laser. + *

+ * This will destroy the laser for every player and start execute all runnables passed with {@link Laser#executeEnd} + */ public void stop() { Validate.isTrue(main != null, "Task not started"); main.cancel(); } - public void moveStart(Location location) throws ReflectiveOperationException { - this.start = location; - if (main != null) moveInternal(start, guardianID, guardian); + /** + * Gets laser status. + * @return true if the laser is currently running + * (i.e. {@link #start} has been called and the duration is not over) + */ + public boolean isStarted() { + return main != null; } - public void moveStart(Location location, int ticks, Runnable callback) { - startMove = moveInternal(location, ticks, startMove, this::getStart, this::moveStart, callback); - } + /** + * Gets laser type. + * @return LaserType enum constant of this laser + */ + public abstract LaserType getLaserType(); + /** + * Instantly moves the start of the laser to the location provided. + * @param location New start location + * @throws ReflectiveOperationException if a reflection exception occurred during laser moving + */ + public abstract void moveStart(Location location) throws ReflectiveOperationException; + + /** + * Instantly moves the end of the laser to the location provided. + * @param location New end location + * @throws ReflectiveOperationException if a reflection exception occurred during laser moving + */ + public abstract void moveEnd(Location location) throws ReflectiveOperationException; + + /** + * Gets the start location of the laser. + * @return where exactly is the start position of the laser located + */ public Location getStart() { return start; } - public void moveEnd(Location location) throws ReflectiveOperationException { - this.end = location; - if (main != null) moveInternal(end, squidID, squid); + /** + * Gets the end location of the laser. + * @return where exactly is the end position of the laser located + */ + public Location getEnd() { + return end; } - public void moveEnd(Location location, int ticks, Runnable callback) { - endMove = moveInternal(location, ticks, endMove, this::getEnd, this::moveEnd, callback); + /** + * Moves the start of the laser smoothly to the new location, within a given time. + * @param location New start location to go to + * @param ticks Duration (in ticks) to make the move + * @param callback {@link Runnable} to execute at the end of the move (nullable) + */ + public void moveStart(Location location, int ticks, Runnable callback) { + startMove = moveInternal(location, ticks, startMove, this::getStart, this::moveStart, callback); } - public Location getEnd() { - return end; + /** + * Moves the end of the laser smoothly to the new location, within a given time. + * @param location New end location to go to + * @param ticks Duration (in ticks) to make the move + * @param callback {@link Runnable} to execute at the end of the move (nullable) + */ + public void moveEnd(Location location, int ticks, Runnable callback) { + endMove = moveInternal(location, ticks, endMove, this::getEnd, this::moveEnd, callback); } private BukkitTask moveInternal(Location location, int ticks, BukkitTask oldTask, Supplier locationSupplier, ReflectiveConsumer moveConsumer, Runnable callback) { Validate.isTrue(ticks > 0); + Validate.isTrue(plugin != null, "Task didn't start once"); if (oldTask != null && !oldTask.isCancelled()) oldTask.cancel(); return new BukkitRunnable() { double xPerTick = (location.getX() - locationSupplier.get().getX()) / ticks; @@ -190,7 +235,7 @@ private BukkitTask moveInternal(Location location, int ticks, BukkitTask oldTask public void run() { try { moveConsumer.accept(locationSupplier.get().add(xPerTick, yPerTick, zPerTick)); - } catch (ReflectiveOperationException e) { + }catch (ReflectiveOperationException e) { e.printStackTrace(); cancel(); return; @@ -204,12 +249,14 @@ public void run() { }.runTaskTimer(plugin, 0L, 1L); } - private void moveInternal(Location location, int entityId, Object fakeEntity) throws ReflectiveOperationException { + protected void moveFakeEntity(Location location, int entityId, Object fakeEntity) throws ReflectiveOperationException { + if (fakeEntity != null) Packets.moveFakeEntity(fakeEntity, location); + if (main == null) return; + Object packet; if (fakeEntity == null) { packet = Packets.createPacketMoveEntity(location, entityId); - } else { - Packets.moveFakeEntity(fakeEntity, location); + }else { packet = Packets.createPacketMoveEntity(fakeEntity); } for (Player p : show) { @@ -217,57 +264,381 @@ private void moveInternal(Location location, int entityId, Object fakeEntity) th } } - public void callColorChange() throws ReflectiveOperationException { - for (Player p : show) { - Packets.sendPackets(p, metadataPacketGuardian); - } - } + protected abstract void sendStartPackets(Player p, boolean hasSeen) throws ReflectiveOperationException; - public boolean isStarted() { - return main != null; + protected abstract void sendDestroyPackets(Player p) throws ReflectiveOperationException; + + protected boolean isCloseEnough(Player player) { + if (distanceSquared == -1) return true; + Location location = player.getLocation(); + return getStart().distanceSquared(location) <= distanceSquared || + getEnd().distanceSquared(location) <= distanceSquared; } - private void sendStartPackets(Player p) throws ReflectiveOperationException { - Packets.sendPackets(p, createSquidPacket, createGuardianPacket); - if (Packets.version > 14) { - Packets.sendPackets(p, metadataPacketSquid, metadataPacketGuardian); + public static class GuardianLaser extends Laser { + private static AtomicInteger teamID = new AtomicInteger(ThreadLocalRandom.current().nextInt(0, Integer.MAX_VALUE)); + + private Object createGuardianPacket; + private Object createSquidPacket; + private Object teamCreatePacket; + private Object[] destroyPackets; + private Object metadataPacketGuardian; + private Object metadataPacketSquid; + private Object fakeGuardianDataWatcher; + + private final UUID squidUUID = UUID.randomUUID(); + private final UUID guardianUUID = UUID.randomUUID(); + private final int squidID = Packets.generateEID(); + private final int guardianID = Packets.generateEID(); + private Object squid; + private Object guardian; + + private int targetID; + private UUID targetUUID; + + protected LivingEntity endEntity; + + /** + * Creates a new Guardian Laser instance + * @param start Location where laser will starts + * @param end Location where laser will ends + * @param duration Duration of laser in seconds (-1 if infinite) + * @param distance Distance where laser will be visible (-1 if infinite) + * @throws ReflectiveOperationException if a reflection exception occurred during Laser creation + * @see Laser#start(Plugin, Player[]) to start the laser for certain players. + * @see #durationInTicks() to make the duration in ticks + * @see #executeEnd(Runnable) to add Runnable-s to execute when the laser will stop + * @see #GuardianLaser(Location, LivingEntity, int, int) to create a laser which follows an entity + */ + public GuardianLaser(Location start, Location end, int duration, int distance) throws ReflectiveOperationException { + super(start, end, duration, distance); + + initSquid(); + + targetID = squidID; + targetUUID = squidUUID; + + initLaser(); + } + + /** + * Creates a new Guardian Laser instance + * @param start Location where laser will starts + * @param endEntity Entity who the laser will follow + * @param duration Duration of laser in seconds (-1 if infinite) + * @param distance Distance where laser will be visible (-1 if infinite) + * @throws ReflectiveOperationException if a reflection exception occurred during Laser creation + * @see #durationInTicks() to make the duration in ticks + * @see #executeEnd(Runnable) to add Runnable-s to execute when the laser will stop + * @see #GuardianLaser(Location, Location, int, int) to create a laser with a specific end location + */ + public GuardianLaser(Location start, LivingEntity endEntity, int duration, int distance) throws ReflectiveOperationException { + super(start, endEntity.getLocation(), duration, distance); + + targetID = endEntity.getEntityId(); + targetUUID = endEntity.getUniqueId(); + + initLaser(); + } + + private void initLaser() throws ReflectiveOperationException { + fakeGuardianDataWatcher = Packets.createFakeDataWatcher(); + Packets.initGuardianWatcher(fakeGuardianDataWatcher, targetID); + if (Packets.version >= 17) { + guardian = Packets.createGuardian(start, guardianUUID, guardianID); + } + metadataPacketGuardian = Packets.createPacketMetadata(guardianID, fakeGuardianDataWatcher); + + teamCreatePacket = Packets.createPacketTeamCreate("noclip" + teamID.getAndIncrement(), squidUUID, guardianUUID); + destroyPackets = Packets.createPacketsRemoveEntities(squidID, guardianID); + } + + private void initSquid() throws ReflectiveOperationException { + if (Packets.version >= 17) { + squid = Packets.createSquid(end, squidUUID, squidID); + } + metadataPacketSquid = Packets.createPacketMetadata(squidID, Packets.fakeSquidWatcher); + Packets.setDirtyWatcher(Packets.fakeSquidWatcher); + } + + private Object getGuardianSpawnPacket() throws ReflectiveOperationException { + if (createGuardianPacket == null) { + if (Packets.version < 17) { + createGuardianPacket = Packets.createPacketEntitySpawnLiving(start, Packets.mappings.getGuardianID(), guardianUUID, guardianID); + }else { + createGuardianPacket = Packets.createPacketEntitySpawnLiving(guardian); + } + } + return createGuardianPacket; + } + + private Object getSquidSpawnPacket() throws ReflectiveOperationException { + if (createSquidPacket == null) { + if (Packets.version < 17) { + createSquidPacket = Packets.createPacketEntitySpawnLiving(end, Packets.mappings.getSquidID(), squidUUID, squidID); + }else { + createSquidPacket = Packets.createPacketEntitySpawnLiving(squid); + } + } + return createSquidPacket; + } + + @Override + public LaserType getLaserType() { + return LaserType.GUARDIAN; + } + + /** + * Makes the laser follow an entity (moving end location). + * + * This is done client-side by making the fake guardian follow the existing entity. + * Hence, there is no consuming of server resources. + * + * @param entity living entity the laser will follow + * @throws ReflectiveOperationException if a reflection operation fails + */ + public void attachEndEntity(LivingEntity entity) throws ReflectiveOperationException { + if (entity.getWorld() != start.getWorld()) throw new IllegalArgumentException("Attached entity is not in the same world as the laser."); + this.endEntity = entity; + setTargetEntity(entity.getUniqueId(), entity.getEntityId()); + } + + public Entity getEndEntity() { + return endEntity; + } + + private void setTargetEntity(UUID uuid, int id) throws ReflectiveOperationException { + targetUUID = uuid; + targetID = id; + fakeGuardianDataWatcher = Packets.createFakeDataWatcher(); + Packets.initGuardianWatcher(fakeGuardianDataWatcher, targetID); + metadataPacketGuardian = Packets.createPacketMetadata(guardianID, fakeGuardianDataWatcher); + + for (Player p : show) { + Packets.sendPackets(p, metadataPacketGuardian); + } + } + + @Override + public Location getEnd() { + return endEntity == null ? end : endEntity.getLocation(); + } + + @Override + protected boolean isCloseEnough(Player player) { + return player == endEntity || super.isCloseEnough(player); + } + + @Override + protected void sendStartPackets(Player p, boolean hasSeen) throws ReflectiveOperationException { + Packets.sendPackets(p, getGuardianSpawnPacket(), getSquidSpawnPacket()); + Packets.sendPackets(p, metadataPacketGuardian, metadataPacketSquid); + if (!hasSeen) Packets.sendPackets(p, teamCreatePacket); + } + + @Override + protected void sendDestroyPackets(Player p) throws ReflectiveOperationException { + Packets.sendPackets(p, destroyPackets); + } + + @Override + public void moveStart(Location location) throws ReflectiveOperationException { + this.start = location; + createGuardianPacket = null; // will force re-generation of spawn packet + moveFakeEntity(start, guardianID, guardian); + } + + @Override + public void moveEnd(Location location) throws ReflectiveOperationException { + this.end = location; + createSquidPacket = null; // will force re-generation of spawn packet + if (squid == null) { + initSquid(); + for (Player p : show) { + Packets.sendPackets(p, createSquidPacket, metadataPacketSquid); + } + }else { + moveFakeEntity(end, squidID, squid); + } + if (targetUUID != squidUUID) { + endEntity = null; + setTargetEntity(squidUUID, squidID); + } } - Packets.sendPackets(p, teamCreatePacket); + + /** + * Asks viewers' clients to change the color of this laser + * @throws ReflectiveOperationException + */ + public void callColourChange() throws ReflectiveOperationException { + for (Player p : show) { + Packets.sendPackets(p, metadataPacketGuardian); + } + } + } - private boolean isCloseEnough(Location location) { - return distanceSquared == -1 || - start.distanceSquared(location) <= distanceSquared || - end.distanceSquared(location) <= distanceSquared; + public static class CrystalLaser extends Laser { + + private Object createCrystalPacket; + private Object metadataPacketCrystal; + private Object[] destroyPackets; + private Object fakeCrystalDataWatcher; + + private final Object crystal; + private final int crystalID = Packets.generateEID(); + + /** + * Creates a new Ender Crystal Laser instance + * @param start Location where laser will starts. The Crystal laser do not handle decimal number, it will be rounded to blocks. + * @param end Location where laser will ends. The Crystal laser do not handle decimal number, it will be rounded to blocks. + * @param duration Duration of laser in seconds (-1 if infinite) + * @param distance Distance where laser will be visible (-1 if infinite) + * @throws ReflectiveOperationException if a reflection exception occurred during Laser creation + * @see #start(Plugin) to start the laser + * @see #durationInTicks() to make the duration in ticks + * @see #executeEnd(Runnable) to add Runnable-s to execute when the laser will stop + */ + public CrystalLaser(Location start, Location end, int duration, int distance) throws ReflectiveOperationException { + super(start, end, duration, distance); + + fakeCrystalDataWatcher = Packets.createFakeDataWatcher(); + Packets.setCrystalWatcher(fakeCrystalDataWatcher, end); + if (Packets.version < 17) { + crystal = null; + }else { + crystal = Packets.createCrystal(start, UUID.randomUUID(), crystalID); + } + metadataPacketCrystal = Packets.createPacketMetadata(crystalID, fakeCrystalDataWatcher); + + destroyPackets = Packets.createPacketsRemoveEntities(crystalID); + } + + private Object getCrystalSpawnPacket() throws ReflectiveOperationException { + if (createCrystalPacket == null) { + if (Packets.version < 17) { + createCrystalPacket = Packets.createPacketEntitySpawnNormal(start, Packets.crystalID, Packets.crystalType, crystalID); + }else { + createCrystalPacket = Packets.createPacketEntitySpawnNormal(crystal); + } + } + return createCrystalPacket; + } + + @Override + public LaserType getLaserType() { + return LaserType.ENDER_CRYSTAL; + } + + @Override + protected void sendStartPackets(Player p, boolean hasSeen) throws ReflectiveOperationException { + Packets.sendPackets(p, getCrystalSpawnPacket()); + Packets.sendPackets(p, metadataPacketCrystal); + } + + @Override + protected void sendDestroyPackets(Player p) throws ReflectiveOperationException { + Packets.sendPackets(p, destroyPackets); + } + + @Override + public void moveStart(Location location) throws ReflectiveOperationException { + this.start = location; + createCrystalPacket = null; // will force re-generation of spawn packet + moveFakeEntity(start, crystalID, crystal); + } + + @Override + public void moveEnd(Location location) throws ReflectiveOperationException { + this.end = location; + if (main != null) { + Packets.setCrystalWatcher(fakeCrystalDataWatcher, location); + metadataPacketCrystal = Packets.createPacketMetadata(crystalID, fakeCrystalDataWatcher); + for (Player p : show) { + Packets.sendPackets(p, metadataPacketCrystal); + } + } + } + } + public enum LaserType { + /** + * Represents a laser from a Guardian entity. + *

+ * It can be pointed to precise locations and + * can track entities smoothly using {@link GuardianLaser#attachEndEntity(LivingEntity)} + */ + GUARDIAN, + + /** + * Represents a laser from an Ender Crystal entity. + *

+ * Start and end locations are automatically rounded to integers (block locations). + */ + ENDER_CRYSTAL; + + /** + * Creates a new Laser instance, {@link GuardianLaser} or {@link CrystalLaser} depending on this enum value. + * @param start Location where laser will starts + * @param end Location where laser will ends + * @param duration Duration of laser in seconds (-1 if infinite) + * @param distance Distance where laser will be visible + * @throws ReflectiveOperationException if a reflection exception occurred during Laser creation + * @see Laser#start(Plugin) to start the laser + * @see Laser#durationInTicks() to make the duration in ticks + * @see Laser#executeEnd(Runnable) to add Runnable-s to execute when the laser will stop + */ + public Laser create(Location start, Location end, int duration, int distance) throws ReflectiveOperationException { + switch (this) { + case ENDER_CRYSTAL: + return new CrystalLaser(start, end, duration, distance); + case GUARDIAN: + return new GuardianLaser(start, end, duration, distance); + } + throw new IllegalStateException(); + } + } private static class Packets { - private static int lastIssuedEID = 2000000000; + private static AtomicInteger lastIssuedEID = new AtomicInteger(2000000000); static int generateEID() { - return lastIssuedEID++; + return lastIssuedEID.getAndIncrement(); } - private static String[] versions = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3].substring(1).split("_"); - private static int version = Integer.parseInt(versions[1]); // 1.X - private static int versionMinor = Integer.parseInt(versions[2].substring(1)); // 1.X.Y + private static Logger logger; + private static int version; + private static int versionMinor; private static String npack = "net.minecraft.server." + Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3]; private static String cpack = Bukkit.getServer().getClass().getPackage().getName() + "."; + private static ProtocolMappings mappings; + + private static int crystalID = 51; // pre-1.13 - private static int squidID; - private static int guardianID; + private static Object crystalType; + private static Object squidType; + private static Object guardianType; + + private static Constructor crystalConstructor; + private static Constructor squidConstructor; + private static Constructor guardianConstructor; private static Object watcherObject1; // invisilibity private static Object watcherObject2; // spikes private static Object watcherObject3; // attack id + private static Object watcherObject4; // crystal target + private static Object watcherObject5; // crystal base plate private static Constructor watcherConstructor; private static Method watcherSet; private static Method watcherRegister; private static Method watcherDirty; - private static Constructor packetSpawn; + private static Constructor blockPositionConstructor; + + private static Constructor packetSpawnLiving; + private static Constructor packetSpawnNormal; private static Constructor packetRemove; private static Constructor packetTeleport; private static Constructor packetMetadata; @@ -284,6 +655,8 @@ static int generateEID() { private static Field playerConnection; private static Method sendPacket; private static Method setLocation; + private static Method setUUID; + private static Method setID; private static Object fakeSquid; private static Object fakeSquidWatcher; @@ -293,104 +666,122 @@ static int generateEID() { public static boolean enabled = false; static { - try { - String watcherName1, watcherName2, watcherName3; - if (version < 13) { - watcherName1 = "Z"; - watcherName2 = "bA"; - watcherName3 = "bB"; - squidID = 94; - guardianID = 68; - } else if (version == 13) { - watcherName1 = "ac"; - watcherName2 = "bF"; - watcherName3 = "bG"; - squidID = 70; - guardianID = 28; - } else if (version == 14) { - watcherName1 = "W"; - watcherName2 = "b"; - watcherName3 = "bD"; - squidID = 73; - guardianID = 30; - } else if (version == 15) { - watcherName1 = "T"; - watcherName2 = "b"; - watcherName3 = "bA"; - squidID = 74; - guardianID = 31; - } else if (version == 16) { - if (versionMinor < 2) { - watcherName1 = "T"; - watcherName2 = "b"; - watcherName3 = "d"; - squidID = 74; - guardianID = 31; + if (SkJade.getInstance().isNmsEnabled()) { + try { + logger = new Logger("GuardianBeam", null) { + @Override + public void log(LogRecord logRecord) { + logRecord.setMessage("[GuardianBeam] " + logRecord.getMessage()); + super.log(logRecord); + } + }; + logger.setParent(Bukkit.getServer().getLogger()); + logger.setLevel(Level.ALL); + + // e.g. Bukkit.getServer().getClass().getPackage().getName() -> org.bukkit.craftbukkit.v1_17_R1 + String[] versions = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3].substring(1).split("_"); + version = Integer.parseInt(versions[1]); // 1.X + if (version >= 17) { + // e.g. Bukkit.getBukkitVersion() -> 1.17.1-R0.1-SNAPSHOT + versions = Bukkit.getBukkitVersion().split("-R")[0].split("\\."); + versionMinor = versions.length <= 2 ? 0 : Integer.parseInt(versions[2]); + } else versionMinor = Integer.parseInt(versions[2].substring(1)); // 1.X.Y + + mappings = ProtocolMappings.getMappings(version); + if (mappings == null) { + mappings = ProtocolMappings.values()[ProtocolMappings.values().length - 1]; + logger.warning("Loaded not matching version of the mappings for your server version (1." + version + "." + versionMinor + ")"); + } + logger.info("Loaded mappings " + mappings.name()); + + Class entityTypesClass = getNMSClass("world.entity", "EntityTypes"); + Class entityClass = getNMSClass("world.entity", "Entity"); + Class crystalClass = getNMSClass("world.entity.boss.enderdragon", "EntityEnderCrystal"); + Class squidClass = getNMSClass("world.entity.animal", "EntitySquid"); + Class guardianClass = getNMSClass("world.entity.monster", "EntityGuardian"); + watcherObject1 = getField(entityClass, mappings.getWatcherFlags(), null); + watcherObject2 = getField(guardianClass, mappings.getWatcherSpikes(), null); + watcherObject3 = getField(guardianClass, mappings.getWatcherTargetEntity(), null); + watcherObject4 = getField(crystalClass, mappings.getWatcherTargetLocation(), null); + watcherObject5 = getField(crystalClass, mappings.getWatcherBasePlate(), null); + + if (version >= 13) { + crystalType = entityTypesClass.getDeclaredField(mappings.getCrystalTypeName()).get(null); + if (version >= 17) { + squidType = entityTypesClass.getDeclaredField("aJ").get(null); + guardianType = entityTypesClass.getDeclaredField("K").get(null); + } + } + + Class dataWatcherClass = getNMSClass("network.syncher", "DataWatcher"); + watcherConstructor = dataWatcherClass.getDeclaredConstructor(entityClass); + if (version >= 18) { + watcherSet = dataWatcherClass.getDeclaredMethod("b", watcherObject1.getClass(), Object.class); + watcherRegister = dataWatcherClass.getDeclaredMethod("a", watcherObject1.getClass(), Object.class); } else { - watcherName1 = "S"; - watcherName2 = "b"; - watcherName3 = "d"; - squidID = 81; - guardianID = 31; + watcherSet = getMethod(dataWatcherClass, "set"); + watcherRegister = getMethod(dataWatcherClass, "register"); + } + if (version >= 15) watcherDirty = getMethod(dataWatcherClass, "markDirty"); + packetSpawnLiving = getNMSClass("network.protocol.game", "PacketPlayOutSpawnEntityLiving").getDeclaredConstructor(version < 17 ? new Class[0] : new Class[]{getNMSClass("world.entity", "EntityLiving")}); + packetSpawnNormal = getNMSClass("network.protocol.game", "PacketPlayOutSpawnEntity").getDeclaredConstructor(version < 17 ? new Class[0] : new Class[]{getNMSClass("world.entity", "Entity")}); + packetRemove = getNMSClass("network.protocol.game", "PacketPlayOutEntityDestroy").getDeclaredConstructor(version == 17 && versionMinor == 0 ? int.class : int[].class); + packetMetadata = getNMSClass("network.protocol.game", "PacketPlayOutEntityMetadata").getDeclaredConstructor(int.class, dataWatcherClass, boolean.class); + packetTeleport = getNMSClass("network.protocol.game", "PacketPlayOutEntityTeleport").getDeclaredConstructor(version < 17 ? new Class[0] : new Class[]{entityClass}); + packetTeam = getNMSClass("network.protocol.game", "PacketPlayOutScoreboardTeam"); + + blockPositionConstructor = getNMSClass("core", "BlockPosition").getConstructor(double.class, double.class, double.class); + + nmsWorld = Class.forName(cpack + "CraftWorld").getDeclaredMethod("getHandle").invoke(Bukkit.getWorlds().get(0)); + + squidConstructor = squidClass.getDeclaredConstructors()[0]; + if (version >= 17) { + guardianConstructor = guardianClass.getDeclaredConstructors()[0]; + crystalConstructor = crystalClass.getDeclaredConstructor(nmsWorld.getClass().getSuperclass(), double.class, double.class, double.class); + } + + Object[] entityConstructorParams = version < 14 ? new Object[]{nmsWorld} : new Object[]{entityTypesClass.getDeclaredField(version < 17 ? "SQUID" : "aJ").get(null), nmsWorld}; + fakeSquid = squidConstructor.newInstance(entityConstructorParams); + fakeSquidWatcher = createFakeDataWatcher(); + tryWatcherSet(fakeSquidWatcher, watcherObject1, (byte) 32); + + getHandle = Class.forName(cpack + "entity.CraftPlayer").getDeclaredMethod("getHandle"); + playerConnection = getNMSClass("server.level", "EntityPlayer").getDeclaredField(version < 17 ? "playerConnection" : "b"); + sendPacket = getNMSClass("server.network", "PlayerConnection").getMethod(version < 18 ? "sendPacket" : "a", getNMSClass("network.protocol", "Packet")); + + if (version >= 17) { + setLocation = entityClass.getDeclaredMethod(version < 18 ? "setLocation" : "a", double.class, double.class, double.class, float.class, float.class); + setUUID = entityClass.getDeclaredMethod("a_", UUID.class); + setID = entityClass.getDeclaredMethod("e", int.class); + + createTeamPacket = packetTeam.getMethod("a", getNMSClass("world.scores", "ScoreboardTeam"), boolean.class); + + Class scoreboardClass = getNMSClass("world.scores", "Scoreboard"); + Class teamClass = getNMSClass("world.scores", "ScoreboardTeam"); + Class pushClass = getNMSClass("world.scores", "ScoreboardTeamBase$EnumTeamPush"); + createTeam = teamClass.getDeclaredConstructor(scoreboardClass, String.class); + createScoreboard = scoreboardClass.getDeclaredConstructor(); + setTeamPush = teamClass.getDeclaredMethod(mappings.getTeamSetCollision(), pushClass); + pushNever = pushClass.getDeclaredField("b").get(null); + getTeamPlayers = teamClass.getDeclaredMethod(mappings.getTeamGetPlayers()); } - } else { // 1.17 - watcherName1 = "Z"; - watcherName2 = "b"; - watcherName3 = "e"; - squidID = 86; - guardianID = 35; - } - Class entityClass = getNMSClass("world.entity", "Entity"); - watcherObject1 = getField(entityClass, watcherName1, null); - watcherObject2 = getField(getNMSClass("world.entity.monster", "EntityGuardian"), watcherName2, null); - watcherObject3 = getField(getNMSClass("world.entity.monster", "EntityGuardian"), watcherName3, null); - - Class dataWatcherClass = getNMSClass("network.syncher", "DataWatcher"); - watcherConstructor = dataWatcherClass.getDeclaredConstructor(entityClass); - watcherSet = getMethod(dataWatcherClass, "set"); - watcherRegister = getMethod(dataWatcherClass, "register"); - if (version >= 15) watcherDirty = getMethod(dataWatcherClass, "markDirty"); - packetSpawn = getNMSClass("network.protocol.game", "PacketPlayOutSpawnEntityLiving").getDeclaredConstructor(version < 17 ? new Class[0] : new Class[]{getNMSClass("world.entity", "EntityLiving")}); packetRemove = getNMSClass("network.protocol.game", "PacketPlayOutEntityDestroy").getDeclaredConstructor(version == 17 && versionMinor == 0 ? int.class : int[].class); - packetRemove = getNMSClass("network.protocol.game", "PacketPlayOutEntityDestroy").getDeclaredConstructor(version == 17 && versionMinor == 0 ? int.class : int[].class); - packetMetadata = getNMSClass("network.protocol.game", "PacketPlayOutEntityMetadata").getDeclaredConstructor(int.class, dataWatcherClass, boolean.class); - packetTeleport = getNMSClass("network.protocol.game", "PacketPlayOutEntityTeleport").getDeclaredConstructor(version < 17 ? new Class[0] : new Class[]{entityClass}); - packetTeam = getNMSClass("network.protocol.game", "PacketPlayOutScoreboardTeam"); - - nmsWorld = Class.forName(cpack + "CraftWorld").getDeclaredMethod("getHandle").invoke(Bukkit.getWorlds().get(0)); - Object[] entityConstructorParams = version < 14 ? new Object[]{nmsWorld} : new Object[]{getNMSClass("world.entity", "EntityTypes").getDeclaredField(version < 17 ? "SQUID" : "aJ").get(null), nmsWorld}; - fakeSquid = getNMSClass("world.entity.animal", "EntitySquid").getDeclaredConstructors()[0].newInstance(entityConstructorParams); - fakeSquidWatcher = createFakeDataWatcher(); - tryWatcherSet(fakeSquidWatcher, watcherObject1, (byte) 32); - - getHandle = Class.forName(cpack + "entity.CraftPlayer").getDeclaredMethod("getHandle"); - playerConnection = getNMSClass("server.level", "EntityPlayer").getDeclaredField(version < 17 ? "playerConnection" : "b"); - sendPacket = getNMSClass("server.network", "PlayerConnection").getMethod("sendPacket", getNMSClass("network.protocol", "Packet")); - - if (version >= 17) { - setLocation = entityClass.getDeclaredMethod("setLocation", double.class, double.class, double.class, float.class, float.class); - - createTeamPacket = packetTeam.getMethod("a", getNMSClass("world.scores", "ScoreboardTeam"), boolean.class); - - Class scoreboardClass = getNMSClass("world.scores", "Scoreboard"); - Class teamClass = getNMSClass("world.scores", "ScoreboardTeam"); - Class pushClass = getNMSClass("world.scores", "ScoreboardTeamBase$EnumTeamPush"); - createTeam = teamClass.getDeclaredConstructor(scoreboardClass, String.class); - createScoreboard = scoreboardClass.getDeclaredConstructor(); - setTeamPush = teamClass.getDeclaredMethod("setCollisionRule", pushClass); - pushNever = pushClass.getDeclaredField("b").get(null); - getTeamPlayers = teamClass.getDeclaredMethod("getPlayerNameSet"); - } - enabled = true; - } catch (ReflectiveOperationException e) { - e.printStackTrace(); - System.err.println("Laser Beam reflection failed to initialize. The util is disabled. Please ensure your version (" + Bukkit.getServer().getClass().getPackage().getName() + ") is supported."); + enabled = true; + } catch (ReflectiveOperationException e) { + e.printStackTrace(); + String errorMsg = "Laser Beam reflection failed to initialize. The util is disabled. Please ensure your version (" + Bukkit.getServer().getClass().getPackage().getName() + ") is supported."; + if (logger == null) + System.err.println(errorMsg); + else + logger.severe(errorMsg); + } } } public static void sendPackets(Player p, Object... packets) throws ReflectiveOperationException { Object connection = playerConnection.get(getHandle.invoke(p)); for (Object packet : packets) { + if (packet == null) continue; sendPacket.invoke(connection, packet); } } @@ -405,23 +796,31 @@ public static void setDirtyWatcher(Object watcher) throws ReflectiveOperationExc if (version >= 15) watcherDirty.invoke(watcher, watcherObject1); } - public static Object createSquid(Location location) throws ReflectiveOperationException { - Object entity = getNMSClass("world.entity.animal", "EntitySquid").getDeclaredConstructors()[0].newInstance(getNMSClass("world.entity", "EntityTypes").getDeclaredField("aJ").get(null), nmsWorld); + public static Object createSquid(Location location, UUID uuid, int id) throws ReflectiveOperationException { + Object entity = squidConstructor.newInstance(squidType, nmsWorld); + setEntityIDs(entity, uuid, id); moveFakeEntity(entity, location); return entity; } - public static Object createGuardian(Location location) throws ReflectiveOperationException { - Object entity = getNMSClass("world.entity.monster", "EntityGuardian").getDeclaredConstructors()[0].newInstance(getNMSClass("world.entity", "EntityTypes").getDeclaredField("K").get(null), nmsWorld); + public static Object createGuardian(Location location, UUID uuid, int id) throws ReflectiveOperationException { + Object entity = guardianConstructor.newInstance(guardianType, nmsWorld); + setEntityIDs(entity, uuid, id); moveFakeEntity(entity, location); return entity; } - public static Object createPacketSquidSpawn(Location location) throws ReflectiveOperationException { - Object packet = packetSpawn.newInstance(); - setField(packet, "a", generateEID()); - setField(packet, "b", UUID.randomUUID()); - setField(packet, "c", squidID); + public static Object createCrystal(Location location, UUID uuid, int id) throws ReflectiveOperationException { + Object entity = crystalConstructor.newInstance(nmsWorld, location.getX(), location.getY(), location.getZ()); + setEntityIDs(entity, uuid, id); + return entity; + } + + public static Object createPacketEntitySpawnLiving(Location location, int typeID, UUID uuid, int id) throws ReflectiveOperationException { + Object packet = packetSpawnLiving.newInstance(); + setField(packet, "a", id); + setField(packet, "b", uuid); + setField(packet, "c", typeID); setField(packet, "d", location.getX()); setField(packet, "e", location.getY()); setField(packet, "f", location.getZ()); @@ -431,39 +830,48 @@ public static Object createPacketSquidSpawn(Location location) throws Reflective return packet; } - public static Object createPacketEntitySpawn(Object entity) throws ReflectiveOperationException { - return packetSpawn.newInstance(entity); + public static Object createPacketEntitySpawnNormal(Location location, int typeID, Object type, int id) throws ReflectiveOperationException { + Object packet = packetSpawnNormal.newInstance(); + setField(packet, "a", id); + setField(packet, "b", UUID.randomUUID()); + setField(packet, "c", location.getX()); + setField(packet, "d", location.getY()); + setField(packet, "e", location.getZ()); + setField(packet, "i", (int) (location.getYaw() * 256.0F / 360.0F)); + setField(packet, "j", (int) (location.getPitch() * 256.0F / 360.0F)); + setField(packet, "k", version < 13 ? typeID : type); + return packet; } - public static void initGuardianWatcher(Object watcher, int squidId) throws ReflectiveOperationException { + public static Object createPacketEntitySpawnLiving(Object entity) throws ReflectiveOperationException { + return packetSpawnLiving.newInstance(entity); + } + + public static Object createPacketEntitySpawnNormal(Object entity) throws ReflectiveOperationException { + return packetSpawnNormal.newInstance(entity); + } + + public static void initGuardianWatcher(Object watcher, int targetId) throws ReflectiveOperationException { tryWatcherSet(watcher, watcherObject1, (byte) 32); - tryWatcherSet(watcher, watcherObject2, false); - tryWatcherSet(watcher, watcherObject3, squidId); + tryWatcherSet(watcher, watcherObject2, Boolean.FALSE); + tryWatcherSet(watcher, watcherObject3, targetId); } - public static Object createPacketGuardianSpawn(Location location, Object watcher, int squidId) throws ReflectiveOperationException { - Object packet = packetSpawn.newInstance(); - setField(packet, "a", generateEID()); - setField(packet, "b", UUID.randomUUID()); - setField(packet, "c", guardianID); - setField(packet, "d", location.getX()); - setField(packet, "e", location.getY()); - setField(packet, "f", location.getZ()); - setField(packet, "j", (byte) (location.getYaw() * 256.0F / 360.0F)); - setField(packet, "k", (byte) (location.getPitch() * 256.0F / 360.0F)); - if (version <= 14) setField(packet, "m", watcher); - return packet; + public static void setCrystalWatcher(Object watcher, Location target) throws ReflectiveOperationException { + Object blockPosition = blockPositionConstructor.newInstance(target.getX(), target.getY(), target.getZ()); + tryWatcherSet(watcher, watcherObject4, version < 13 ? com.google.common.base.Optional.of(blockPosition) : Optional.of(blockPosition)); + tryWatcherSet(watcher, watcherObject5, Boolean.FALSE); } public static Object[] createPacketsRemoveEntities(int... entitiesId) throws ReflectiveOperationException { Object[] packets; - if (version < 17 || (version == 17 && versionMinor != 0)) { - packets = new Object[]{packetRemove.newInstance(entitiesId)}; - } else { + if (version == 17 && versionMinor == 0) { packets = new Object[entitiesId.length]; for (int i = 0; i < entitiesId.length; i++) { packets[i] = packetRemove.newInstance(entitiesId[i]); } + }else { + packets = new Object[] { packetRemove.newInstance(entitiesId) }; } return packets; } @@ -480,6 +888,11 @@ public static Object createPacketMoveEntity(Location location, int entityId) thr return packet; } + public static void setEntityIDs(Object entity, UUID uuid, int id) throws ReflectiveOperationException { + setUUID.invoke(entity, uuid); + setID.invoke(entity, id); + } + public static void moveFakeEntity(Object entity, Location location) throws ReflectiveOperationException { setLocation.invoke(entity, location.getX(), location.getY(), location.getZ(), location.getPitch(), location.getYaw()); } @@ -488,7 +901,7 @@ public static Object createPacketMoveEntity(Object entity) throws ReflectiveOper return packetTeleport.newInstance(entity); } - public static Object createPacketTeamCreate(String teamName, UUID squidUUID, UUID guardianUUID) throws ReflectiveOperationException { + public static Object createPacketTeamCreate(String teamName, UUID... entities) throws ReflectiveOperationException { Object packet; if (version < 17) { packet = packetTeam.newInstance(); @@ -496,14 +909,12 @@ public static Object createPacketTeamCreate(String teamName, UUID squidUUID, UUI setField(packet, "i", 0); setField(packet, "f", "never"); Collection players = (Collection) getField(packetTeam, "h", packet); - players.add(squidUUID.toString()); - players.add(guardianUUID.toString()); - } else { + for (UUID entity : entities) players.add(entity.toString()); + }else { Object team = createTeam.newInstance(createScoreboard.newInstance(), teamName); setTeamPush.invoke(team, pushNever); Collection players = (Collection) getTeamPlayers.invoke(team); - players.add(squidUUID.toString()); - players.add(guardianUUID.toString()); + for (UUID entity : entities) players.add(entity.toString()); packet = createTeamPacket.invoke(null, team, true); } return packet; @@ -516,18 +927,18 @@ private static Object createPacketMetadata(int entityId, Object watcher) throws private static void tryWatcherSet(Object watcher, Object watcherObject, Object watcherData) throws ReflectiveOperationException { try { watcherSet.invoke(watcher, watcherObject, watcherData); - } catch (InvocationTargetException ex) { + }catch (InvocationTargetException ex) { watcherRegister.invoke(watcher, watcherObject, watcherData); if (version >= 15) watcherDirty.invoke(watcher, watcherObject); } } /* Reflection utils */ - private static Method getMethod(Class clazz, String name) { + private static Method getMethod(Class clazz, String name) throws NoSuchMethodException { for (Method m : clazz.getDeclaredMethods()) { if (m.getName().equals(name)) return m; } - return null; + throw new NoSuchMethodException(name + " in " + clazz.getName()); } private static void setField(Object instance, String name, Object value) throws ReflectiveOperationException { @@ -558,4 +969,119 @@ private static Class getNMSClass(String package17, String className) throws C public static interface ReflectiveConsumer { abstract void accept(T t) throws ReflectiveOperationException; } -} + + private enum ProtocolMappings { + V1_9(9, "Z", "bA", "bB", "b", "c", 94, 68), + V1_10(10, V1_9), + V1_11(11, V1_10), + V1_12(12, V1_11), + V1_13(13, "ac", "bF", "bG", "b", "c", 70, 28), + V1_14(14, "W", "b", "bD", "c", "d", 73, 30), + V1_15(15, "T", "b", "bA", "c", "d", 74, 31), + V1_16(16, "T", "b", "d", "c", "d", 74, 31, "u", null, null){ + @Override + public int getSquidID() { + return Packets.versionMinor < 2 ? super.getSquidID() : 81; + } + + @Override + public String getWatcherFlags() { + return Packets.versionMinor < 2 ? super.getWatcherFlags() : "S"; + } + }, + V1_17(17, "Z", "b", "e", "c", "d", 86, 35, "u", "setCollisionRule", "getPlayerNameSet"), + V1_18(18, "aa", "b", "e", "c", "d", 86, 35, "u", "a", "g"), + ; + + private final int major; + private final String watcherFlags; + private final String watcherSpikes; + private final String watcherTargetEntity; + private final String watcherTargetLocation; + private final String watcherBasePlate; + private final int squidID; + private final int guardianID; + private final String crystalTypeName; + private final String teamSetCollision; + private final String teamGetPlayers; + + private ProtocolMappings(int major, ProtocolMappings parent) { + this(major, parent.watcherFlags, parent.watcherSpikes, parent.watcherTargetEntity, parent.watcherTargetLocation, parent.watcherBasePlate, parent.squidID, parent.guardianID, parent.crystalTypeName, parent.teamSetCollision, parent.teamGetPlayers); + } + + private ProtocolMappings(int major, + String watcherFlags, String watcherSpikes, String watcherTargetEntity, String watcherTargetLocation, String watcherBasePlate, + int squidID, int guardianID) { + this(major, watcherFlags, watcherSpikes, watcherTargetEntity, watcherTargetLocation, watcherBasePlate, squidID, guardianID, "END_CRYSTAL", null, null); + } + + private ProtocolMappings(int major, + String watcherFlags, String watcherSpikes, String watcherTargetEntity, String watcherTargetLocation, String watcherBasePlate, + int squidID, int guardianID, + String crystalTypeName, String teamSetCollision, String teamGetPlayers) { + this.major = major; + this.watcherFlags = watcherFlags; + this.watcherSpikes = watcherSpikes; + this.watcherTargetEntity = watcherTargetEntity; + this.watcherTargetLocation = watcherTargetLocation; + this.watcherBasePlate = watcherBasePlate; + this.squidID = squidID; + this.guardianID = guardianID; + this.crystalTypeName = crystalTypeName; + this.teamSetCollision = teamSetCollision; + this.teamGetPlayers = teamGetPlayers; + } + + public int getMajor() { + return major; + } + + public String getWatcherFlags() { + return watcherFlags; + } + + public String getWatcherSpikes() { + return watcherSpikes; + } + + public String getWatcherTargetEntity() { + return watcherTargetEntity; + } + + public String getWatcherTargetLocation() { + return watcherTargetLocation; + } + + public String getWatcherBasePlate() { + return watcherBasePlate; + } + + public int getSquidID() { + return squidID; + } + + public int getGuardianID() { + return guardianID; + } + + public String getCrystalTypeName() { + return crystalTypeName; + } + + public String getTeamSetCollision() { + return teamSetCollision; + } + + public String getTeamGetPlayers() { + return teamGetPlayers; + } + + public static ProtocolMappings getMappings(int major) { + for (ProtocolMappings map : values()) { + if (major == map.getMajor()) return map; + } + return null; + } + + } +} \ No newline at end of file diff --git a/src/main/java/com/ankoki/skjade/elements/lasers/effects/EffAttachEndEntity.java b/src/main/java/com/ankoki/skjade/elements/lasers/effects/EffAttachEndEntity.java new file mode 100644 index 0000000..0d692ef --- /dev/null +++ b/src/main/java/com/ankoki/skjade/elements/lasers/effects/EffAttachEndEntity.java @@ -0,0 +1,57 @@ +package com.ankoki.skjade.elements.lasers.effects; + +import ch.njol.skript.Skript; +import ch.njol.skript.doc.Description; +import ch.njol.skript.doc.Examples; +import ch.njol.skript.doc.Name; +import ch.njol.skript.doc.Since; +import ch.njol.skript.lang.Effect; +import ch.njol.skript.lang.Expression; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.util.Kleenean; +import com.ankoki.skjade.SkJade; +import com.ankoki.skjade.elements.lasers.Laser; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; + +@Name("Attach Entity to Laser") +@Description("Attaches a living entity to the end of a laser.") +@Examples("attach event-mob to end of {_laser}") +@Since("1.4") +public class EffAttachEndEntity extends Effect { + + static { + if (SkJade.getInstance().isNmsEnabled()) + Skript.registerEffect(EffAttachEndEntity.class, + "attach %livingentity% to [the] end of %lasers%"); + } + + private Expression entityExpr; + private Expression laserExpr; + + @Override + public boolean init(Expression[] expressions, int i, Kleenean kleenean, ParseResult parseResult) { + entityExpr = (Expression) expressions[0]; + laserExpr = (Expression) expressions[1]; + return true; + } + + @Override + protected void execute(Event event) { + LivingEntity entity = entityExpr.getSingle(event); + Laser[] lasers = laserExpr.getArray(event); + if (entity == null || lasers.length < 1) return; + try { + for (Laser laser : lasers) { + if (entity.getWorld() != laser.getStart().getWorld()) continue; + ((Laser.GuardianLaser) laser).attachEndEntity(entity); + } + } catch (ReflectiveOperationException ex) {} + } + + @Override + public String toString(@Nullable Event event, boolean b) { + return "attach " + entityExpr.toString(event, b) + " to end of " + laserExpr.toString(event, b); + } +} diff --git a/src/main/java/com/ankoki/skjade/elements/lasers/effects/EffChangeLaserColour.java b/src/main/java/com/ankoki/skjade/elements/lasers/effects/EffChangeLaserColour.java index 5abdcae..b780a29 100644 --- a/src/main/java/com/ankoki/skjade/elements/lasers/effects/EffChangeLaserColour.java +++ b/src/main/java/com/ankoki/skjade/elements/lasers/effects/EffChangeLaserColour.java @@ -9,6 +9,7 @@ import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.util.Kleenean; +import com.ankoki.skjade.SkJade; import com.ankoki.skjade.elements.lasers.Laser; import org.bukkit.event.Event; import org.jetbrains.annotations.Nullable; @@ -20,7 +21,8 @@ public class EffChangeLaserColour extends Effect { static { - Skript.registerEffect(EffChangeLaserColour.class, + if (SkJade.getInstance().isNmsEnabled()) + Skript.registerEffect(EffChangeLaserColour.class, "(force|make) %lasers% [to] change colo[u]r[[']s]"); } @@ -32,7 +34,7 @@ protected void execute(Event e) { for (Laser laser : lasers) { if (laser.isStarted()) { try { - laser.callColorChange(); + ((Laser.GuardianLaser) laser).callColourChange(); } catch (Exception ex) { ex.printStackTrace(); } diff --git a/src/main/java/com/ankoki/skjade/elements/lasers/effects/EffCreateLaser.java b/src/main/java/com/ankoki/skjade/elements/lasers/effects/EffCreateLaser.java index 8fc3adb..b16a4f3 100644 --- a/src/main/java/com/ankoki/skjade/elements/lasers/effects/EffCreateLaser.java +++ b/src/main/java/com/ankoki/skjade/elements/lasers/effects/EffCreateLaser.java @@ -10,6 +10,7 @@ import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.util.Timespan; import ch.njol.util.Kleenean; +import com.ankoki.skjade.SkJade; import com.ankoki.skjade.elements.lasers.LaserManager; import com.ankoki.skjade.elements.lasers.Laser; import org.bukkit.Location; @@ -23,7 +24,8 @@ public class EffCreateLaser extends Effect { static { - Skript.registerEffect(EffCreateLaser.class, + if (SkJade.getInstance().isNmsEnabled()) + Skript.registerEffect(EffCreateLaser.class, "create [a] [new] (la(s|z)er [beam]|guardian beam) from %location% to %location% for %timespan% with [the] id %string%"); } @@ -41,7 +43,7 @@ protected void execute(Event e) { if (loc1 == null || loc2 == null || sec == null || id == null || id.isEmpty()) return; int seconds = (int) Math.ceil(sec.getTicks_i() / 20D); try { - Laser laser = new Laser(loc1, loc2, seconds, 100); + Laser laser = new Laser.GuardianLaser(loc1, loc2, seconds, 100); LaserManager.createLaser(id, laser); } catch (Exception ex) { ex.printStackTrace(); diff --git a/src/main/java/com/ankoki/skjade/elements/lasers/effects/EffShowLaser.java b/src/main/java/com/ankoki/skjade/elements/lasers/effects/EffShowLaser.java index d63b48d..ffddd62 100644 --- a/src/main/java/com/ankoki/skjade/elements/lasers/effects/EffShowLaser.java +++ b/src/main/java/com/ankoki/skjade/elements/lasers/effects/EffShowLaser.java @@ -24,7 +24,8 @@ public class EffShowLaser extends Effect { static { - Skript.registerEffect(EffShowLaser.class, + if (SkJade.getInstance().isNmsEnabled()) + Skript.registerEffect(EffShowLaser.class, "show [a] [new] (la(s|z)er [beam]|guardian beam) from %location% to %location% for %timespan% [for %-players%]"); } @@ -47,7 +48,7 @@ protected void execute(Event e) { } int seconds = (int) Math.ceil(sec.getTicks_i() / 20D); try { - Laser laser = new Laser(loc1, loc2, seconds, 100); + Laser laser = new Laser.GuardianLaser(loc1, loc2, seconds, 100); laser.start(SkJade.getInstance(), players); } catch (Exception ex) { ex.printStackTrace(); //could probably ignore this after testing diff --git a/src/main/java/com/ankoki/skjade/elements/lasers/effects/EffStartLaser.java b/src/main/java/com/ankoki/skjade/elements/lasers/effects/EffStartLaser.java index 534f693..086996a 100644 --- a/src/main/java/com/ankoki/skjade/elements/lasers/effects/EffStartLaser.java +++ b/src/main/java/com/ankoki/skjade/elements/lasers/effects/EffStartLaser.java @@ -22,7 +22,8 @@ public class EffStartLaser extends Effect { static { - Skript.registerEffect(EffStartLaser.class, + if (SkJade.getInstance().isNmsEnabled()) + Skript.registerEffect(EffStartLaser.class, "start %laser% [for %-players%]"); } diff --git a/src/main/java/com/ankoki/skjade/elements/lasers/effects/EffStopLaser.java b/src/main/java/com/ankoki/skjade/elements/lasers/effects/EffStopLaser.java index f7157ab..999b604 100644 --- a/src/main/java/com/ankoki/skjade/elements/lasers/effects/EffStopLaser.java +++ b/src/main/java/com/ankoki/skjade/elements/lasers/effects/EffStopLaser.java @@ -9,6 +9,7 @@ import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.util.Kleenean; +import com.ankoki.skjade.SkJade; import com.ankoki.skjade.elements.lasers.Laser; import org.bukkit.event.Event; import org.jetbrains.annotations.Nullable; @@ -20,7 +21,8 @@ public class EffStopLaser extends Effect { static { - Skript.registerEffect(EffStopLaser.class, + if (SkJade.getInstance().isNmsEnabled()) + Skript.registerEffect(EffStopLaser.class, "stop %lasers%"); } diff --git a/src/main/java/com/ankoki/skjade/elements/lasers/expressions/ExprLaser.java b/src/main/java/com/ankoki/skjade/elements/lasers/expressions/ExprLaser.java index 955240a..7d78fd8 100644 --- a/src/main/java/com/ankoki/skjade/elements/lasers/expressions/ExprLaser.java +++ b/src/main/java/com/ankoki/skjade/elements/lasers/expressions/ExprLaser.java @@ -10,6 +10,7 @@ import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.lang.util.SimpleExpression; import ch.njol.util.Kleenean; +import com.ankoki.skjade.SkJade; import com.ankoki.skjade.elements.lasers.LaserManager; import com.ankoki.skjade.elements.lasers.Laser; import org.bukkit.event.Event; @@ -22,7 +23,8 @@ public class ExprLaser extends SimpleExpression { static { - Skript.registerExpression(ExprLaser.class, Laser.class, ExpressionType.SIMPLE, + if (SkJade.getInstance().isNmsEnabled()) + Skript.registerExpression(ExprLaser.class, Laser.class, ExpressionType.SIMPLE, "[the] (la(s|z)er [beam]|guardian beam) with [the] id %string%"); } diff --git a/src/main/java/com/ankoki/skjade/elements/lasers/expressions/ExprLaserPoints.java b/src/main/java/com/ankoki/skjade/elements/lasers/expressions/ExprLaserPoints.java index 9f346b4..4aee084 100644 --- a/src/main/java/com/ankoki/skjade/elements/lasers/expressions/ExprLaserPoints.java +++ b/src/main/java/com/ankoki/skjade/elements/lasers/expressions/ExprLaserPoints.java @@ -12,6 +12,7 @@ import ch.njol.skript.lang.util.SimpleExpression; import ch.njol.util.Kleenean; import ch.njol.util.coll.CollectionUtils; +import com.ankoki.skjade.SkJade; import com.ankoki.skjade.elements.lasers.Laser; import org.bukkit.Location; import org.bukkit.event.Event; @@ -24,7 +25,8 @@ public class ExprLaserPoints extends SimpleExpression { static { - Skript.registerExpression(ExprLaserPoints.class, Location.class, ExpressionType.SIMPLE, + if (SkJade.getInstance().isNmsEnabled()) + Skript.registerExpression(ExprLaserPoints.class, Location.class, ExpressionType.SIMPLE, "[the] (1¦start|end)[ing] [loc[ation]] of %laser%"); } diff --git a/src/main/java/com/ankoki/skjade/hooks/elementals/EleClassInfo.java b/src/main/java/com/ankoki/skjade/hooks/elementals/EleClassInfo.java index d5f0233..0d6ce6c 100644 --- a/src/main/java/com/ankoki/skjade/hooks/elementals/EleClassInfo.java +++ b/src/main/java/com/ankoki/skjade/hooks/elementals/EleClassInfo.java @@ -31,7 +31,6 @@ public String toVariableNameString(Spell spell) { return spell.getSpellName().toLowerCase(); } - @Override public String getVariableNamePattern() { return "\\S+"; } diff --git a/src/main/java/com/ankoki/skjade/hooks/elementals/conditions/CondCanCastSpell.java b/src/main/java/com/ankoki/skjade/hooks/elementals/conditions/CondCanCastSpell.java index b9784ee..1c01867 100644 --- a/src/main/java/com/ankoki/skjade/hooks/elementals/conditions/CondCanCastSpell.java +++ b/src/main/java/com/ankoki/skjade/hooks/elementals/conditions/CondCanCastSpell.java @@ -9,7 +9,7 @@ import com.ankoki.elementals.managers.Spell; import org.bukkit.entity.Player; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Can Cast Spell") @Description("Checks if a player can cast the spell specified") diff --git a/src/main/java/com/ankoki/skjade/hooks/elementals/conditions/CondSpellExists.java b/src/main/java/com/ankoki/skjade/hooks/elementals/conditions/CondSpellExists.java index 625d0a6..55bce4e 100644 --- a/src/main/java/com/ankoki/skjade/hooks/elementals/conditions/CondSpellExists.java +++ b/src/main/java/com/ankoki/skjade/hooks/elementals/conditions/CondSpellExists.java @@ -8,7 +8,7 @@ import ch.njol.util.Kleenean; import com.ankoki.elementals.managers.Spell; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Spell Exists") @Description("Checks if an elementals spell exists.") diff --git a/src/main/java/com/ankoki/skjade/hooks/elementals/conditions/CondSpellType.java b/src/main/java/com/ankoki/skjade/hooks/elementals/conditions/CondSpellType.java index ae89447..56f7f7d 100644 --- a/src/main/java/com/ankoki/skjade/hooks/elementals/conditions/CondSpellType.java +++ b/src/main/java/com/ankoki/skjade/hooks/elementals/conditions/CondSpellType.java @@ -11,7 +11,7 @@ import com.ankoki.elementals.managers.Spell; import com.ankoki.skjade.utils.Utils.SpellType; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Spell Type") @Description("Checks if the spell is either generic, entity, prolonged generic, or prolonged entity.") diff --git a/src/main/java/com/ankoki/skjade/hooks/elementals/effects/EffCreateSpell.java b/src/main/java/com/ankoki/skjade/hooks/elementals/effects/EffCreateSpell.java index b829dd1..38add15 100644 --- a/src/main/java/com/ankoki/skjade/hooks/elementals/effects/EffCreateSpell.java +++ b/src/main/java/com/ankoki/skjade/hooks/elementals/effects/EffCreateSpell.java @@ -18,7 +18,7 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Register Elementals Spell") @Description({"Registers a new elementals spell which can be cast.", diff --git a/src/main/java/com/ankoki/skjade/hooks/elementals/effects/EffEnchantItem.java b/src/main/java/com/ankoki/skjade/hooks/elementals/effects/EffEnchantItem.java index c95a43e..c263006 100644 --- a/src/main/java/com/ankoki/skjade/hooks/elementals/effects/EffEnchantItem.java +++ b/src/main/java/com/ankoki/skjade/hooks/elementals/effects/EffEnchantItem.java @@ -11,7 +11,7 @@ import com.ankoki.elementals.managers.Spell; import org.bukkit.event.Event; import org.bukkit.inventory.ItemStack; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Enchant Item") @Description("Add an elementals spell to an item") diff --git a/src/main/java/com/ankoki/skjade/hooks/elementals/events/EvtSpellCancel.java b/src/main/java/com/ankoki/skjade/hooks/elementals/events/EvtSpellCancel.java index 9dbf9fd..43105fb 100644 --- a/src/main/java/com/ankoki/skjade/hooks/elementals/events/EvtSpellCancel.java +++ b/src/main/java/com/ankoki/skjade/hooks/elementals/events/EvtSpellCancel.java @@ -9,7 +9,7 @@ import com.ankoki.elementals.managers.Spell; import org.bukkit.entity.Player; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Prolonged Spell Cancel") @Description("This is called whenever any prolonged spell is cancelled.") diff --git a/src/main/java/com/ankoki/skjade/hooks/elementals/events/EvtSpellCast.java b/src/main/java/com/ankoki/skjade/hooks/elementals/events/EvtSpellCast.java index 0b087ed..18cdf4f 100644 --- a/src/main/java/com/ankoki/skjade/hooks/elementals/events/EvtSpellCast.java +++ b/src/main/java/com/ankoki/skjade/hooks/elementals/events/EvtSpellCast.java @@ -10,7 +10,7 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Spell Cast") @Description("This is called whenever any spell is called.") diff --git a/src/main/java/com/ankoki/skjade/hooks/elementals/expressions/ExprSpell.java b/src/main/java/com/ankoki/skjade/hooks/elementals/expressions/ExprSpell.java index 067ba59..d03a2f6 100644 --- a/src/main/java/com/ankoki/skjade/hooks/elementals/expressions/ExprSpell.java +++ b/src/main/java/com/ankoki/skjade/hooks/elementals/expressions/ExprSpell.java @@ -14,7 +14,7 @@ import com.ankoki.elementals.events.SpellCastEvent; import com.ankoki.elementals.managers.Spell; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Spell") @Description("An elemental spell") diff --git a/src/main/java/com/ankoki/skjade/hooks/elementals/expressions/ExprSpellBook.java b/src/main/java/com/ankoki/skjade/hooks/elementals/expressions/ExprSpellBook.java index cdded43..d4397ca 100644 --- a/src/main/java/com/ankoki/skjade/hooks/elementals/expressions/ExprSpellBook.java +++ b/src/main/java/com/ankoki/skjade/hooks/elementals/expressions/ExprSpellBook.java @@ -12,7 +12,7 @@ import com.ankoki.elementals.managers.Spell; import org.bukkit.event.Event; import org.bukkit.inventory.ItemStack; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Spell Book") @Description("An elemental spell book with the spell name") diff --git a/src/main/java/com/ankoki/skjade/hooks/elementals/expressions/ExprSpellID.java b/src/main/java/com/ankoki/skjade/hooks/elementals/expressions/ExprSpellID.java index e16de59..003e12a 100644 --- a/src/main/java/com/ankoki/skjade/hooks/elementals/expressions/ExprSpellID.java +++ b/src/main/java/com/ankoki/skjade/hooks/elementals/expressions/ExprSpellID.java @@ -9,7 +9,7 @@ import ch.njol.util.Kleenean; import com.ankoki.elementals.managers.Spell; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Spell's ID") @Description("An elemental spells ID.") diff --git a/src/main/java/com/ankoki/skjade/hooks/holograms/HoloClassInfo.java b/src/main/java/com/ankoki/skjade/hooks/holograms/HoloClassInfo.java index 0589da1..1d3a64b 100644 --- a/src/main/java/com/ankoki/skjade/hooks/holograms/HoloClassInfo.java +++ b/src/main/java/com/ankoki/skjade/hooks/holograms/HoloClassInfo.java @@ -16,7 +16,7 @@ import com.gmail.filoghost.holographicdisplays.api.line.TextLine; import org.bukkit.Location; import org.bukkit.inventory.ItemStack; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; import java.io.NotSerializableException; import java.io.StreamCorruptedException; @@ -79,11 +79,6 @@ public String toString(Hologram hologram, int i) { public String toVariableNameString(Hologram hologram) { return "hologram:" + hologram.getCreationTimestamp(); } - - @Override - public String getVariableNamePattern() { - return "hologram:\\d+"; - } }) .serializer(new Serializer() { @Override @@ -153,11 +148,6 @@ public String toString(HologramLine hologramLine, int i) { public String toVariableNameString(HologramLine hologramLine) { return hologramLine instanceof ItemLine ? "hologram item line" : "hologram text line"; } - - @Override - public String getVariableNamePattern() { - return "\\S+"; - } })); Converters.registerConverter(TextLine.class, String.class, TextLine::getText); diff --git a/src/main/java/com/ankoki/skjade/hooks/holograms/conditions/CondHasInteractionHandler.java b/src/main/java/com/ankoki/skjade/hooks/holograms/conditions/CondHasInteractionHandler.java index 37ffb64..565001d 100644 --- a/src/main/java/com/ankoki/skjade/hooks/holograms/conditions/CondHasInteractionHandler.java +++ b/src/main/java/com/ankoki/skjade/hooks/holograms/conditions/CondHasInteractionHandler.java @@ -11,7 +11,7 @@ import com.gmail.filoghost.holographicdisplays.api.line.HologramLine; import com.gmail.filoghost.holographicdisplays.api.line.TouchableLine; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Hologram is Interactable/Clickable/Touchable") @Description("Checks if a hologram is interactable, clickable, or touchable") diff --git a/src/main/java/com/ankoki/skjade/hooks/holograms/conditions/CondIsHologram.java b/src/main/java/com/ankoki/skjade/hooks/holograms/conditions/CondIsHologram.java index 804ecb5..2d5b57f 100644 --- a/src/main/java/com/ankoki/skjade/hooks/holograms/conditions/CondIsHologram.java +++ b/src/main/java/com/ankoki/skjade/hooks/holograms/conditions/CondIsHologram.java @@ -9,7 +9,7 @@ import com.gmail.filoghost.holographicdisplays.api.HologramsAPI; import org.bukkit.entity.Entity; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Is A Hologram") @Description("Checks if an entity is a hologram") diff --git a/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffAddItemLine.java b/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffAddItemLine.java index 5003dbc..1301a52 100644 --- a/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffAddItemLine.java +++ b/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffAddItemLine.java @@ -10,7 +10,7 @@ import com.gmail.filoghost.holographicdisplays.api.Hologram; import org.bukkit.event.Event; import org.bukkit.inventory.ItemStack; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Add Item Line") @Description("Adds an item to the hologram.") diff --git a/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffAddTextLine.java b/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffAddTextLine.java index cdfff5f..6863f4e 100644 --- a/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffAddTextLine.java +++ b/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffAddTextLine.java @@ -9,7 +9,7 @@ import com.ankoki.skjade.hooks.holograms.HologramManager; import com.gmail.filoghost.holographicdisplays.api.Hologram; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; import java.util.Arrays; diff --git a/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffCreateHolo.java b/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffCreateHolo.java index 6b79b1a..c05683a 100644 --- a/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffCreateHolo.java +++ b/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffCreateHolo.java @@ -9,7 +9,7 @@ import com.ankoki.skjade.hooks.holograms.HologramManager; import org.bukkit.Location; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Create Hologram") @Description({"Creates a hologram at the specified location with the id specified. The ID must be unique.", diff --git a/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffDeleteHolo.java b/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffDeleteHolo.java index f55a5cf..bc9b722 100644 --- a/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffDeleteHolo.java +++ b/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffDeleteHolo.java @@ -9,7 +9,7 @@ import com.ankoki.skjade.hooks.holograms.HologramManager; import com.gmail.filoghost.holographicdisplays.api.Hologram; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Delete Hologram") @Description("Deletes a hologram") diff --git a/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffInteractableLine.java b/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffInteractableLine.java index d4e3c00..7fe3bf2 100644 --- a/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffInteractableLine.java +++ b/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffInteractableLine.java @@ -11,7 +11,7 @@ import com.gmail.filoghost.holographicdisplays.api.Hologram; import com.gmail.filoghost.holographicdisplays.api.line.HologramLine; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Interactive Hologram Line") @Description("Makes a line of a hologram clickable(triggers the on hologram click), touchable(triggers on hologram touch)," + diff --git a/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffRegisterPlaceholder.java b/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffRegisterPlaceholder.java index d606057..346d14b 100644 --- a/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffRegisterPlaceholder.java +++ b/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffRegisterPlaceholder.java @@ -13,7 +13,7 @@ import com.ankoki.skjade.SkJade; import com.gmail.filoghost.holographicdisplays.api.HologramsAPI; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; /** * @author Mr. Darth c: tyty for da help w function parsing<3 diff --git a/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffRemoveLine.java b/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffRemoveLine.java index e7dd83c..badfe97 100644 --- a/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffRemoveLine.java +++ b/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffRemoveLine.java @@ -10,7 +10,7 @@ import com.gmail.filoghost.holographicdisplays.api.Hologram; import com.gmail.filoghost.holographicdisplays.api.line.HologramLine; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Remove Line") @Description("Removes a line from a hologram") diff --git a/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffResetVisibility.java b/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffResetVisibility.java index b7be5aa..37cf8e3 100644 --- a/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffResetVisibility.java +++ b/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffResetVisibility.java @@ -9,7 +9,7 @@ import com.gmail.filoghost.holographicdisplays.api.Hologram; import org.bukkit.entity.Player; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Reset Visibility") @Description("Resets the visibility of a hologram to its default visibility.") diff --git a/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffSetVisibility.java b/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffSetVisibility.java index 697951d..f591147 100644 --- a/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffSetVisibility.java +++ b/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffSetVisibility.java @@ -9,7 +9,7 @@ import com.gmail.filoghost.holographicdisplays.api.Hologram; import org.bukkit.entity.Player; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Set Visibility") @Description("Sets the visibility of a hologram to show or hide certain players.") diff --git a/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffUnregisterPlaceholder.java b/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffUnregisterPlaceholder.java index 2a6965d..cef76dc 100644 --- a/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffUnregisterPlaceholder.java +++ b/src/main/java/com/ankoki/skjade/hooks/holograms/effects/EffUnregisterPlaceholder.java @@ -9,7 +9,7 @@ import com.ankoki.skjade.SkJade; import com.gmail.filoghost.holographicdisplays.api.HologramsAPI; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Unregister Placeholder") @Description("Unregisters a Holographic Displays placeholder.") diff --git a/src/main/java/com/ankoki/skjade/hooks/holograms/events/EvtHologramLineClick.java b/src/main/java/com/ankoki/skjade/hooks/holograms/events/EvtHologramLineClick.java index 81ee8d4..a30916c 100644 --- a/src/main/java/com/ankoki/skjade/hooks/holograms/events/EvtHologramLineClick.java +++ b/src/main/java/com/ankoki/skjade/hooks/holograms/events/EvtHologramLineClick.java @@ -12,7 +12,7 @@ import com.gmail.filoghost.holographicdisplays.api.line.HologramLine; import org.bukkit.entity.Player; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Hologram Line Click") @Description("Called when an interactable hologram line is clicked.") diff --git a/src/main/java/com/ankoki/skjade/hooks/holograms/events/EvtHologramLineTouch.java b/src/main/java/com/ankoki/skjade/hooks/holograms/events/EvtHologramLineTouch.java index a4babd0..8aa6531 100644 --- a/src/main/java/com/ankoki/skjade/hooks/holograms/events/EvtHologramLineTouch.java +++ b/src/main/java/com/ankoki/skjade/hooks/holograms/events/EvtHologramLineTouch.java @@ -12,7 +12,7 @@ import com.gmail.filoghost.holographicdisplays.api.line.HologramLine; import org.bukkit.entity.Player; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Hologram Line Touch") @Description("Called when an interactable hologram line is touched.") diff --git a/src/main/java/com/ankoki/skjade/hooks/holograms/expressions/ExprHologram.java b/src/main/java/com/ankoki/skjade/hooks/holograms/expressions/ExprHologram.java index 0a5fe80..b389d0e 100644 --- a/src/main/java/com/ankoki/skjade/hooks/holograms/expressions/ExprHologram.java +++ b/src/main/java/com/ankoki/skjade/hooks/holograms/expressions/ExprHologram.java @@ -13,7 +13,7 @@ import com.ankoki.skjade.hooks.holograms.bukkitevents.HologramTouchEvent; import com.gmail.filoghost.holographicdisplays.api.Hologram; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Hologram") @Description("A HolographicDisplays Hologram. The ID of every hologram should be unique.") diff --git a/src/main/java/com/ankoki/skjade/hooks/holograms/expressions/ExprHologramLine.java b/src/main/java/com/ankoki/skjade/hooks/holograms/expressions/ExprHologramLine.java index f8c0771..65fd5da 100644 --- a/src/main/java/com/ankoki/skjade/hooks/holograms/expressions/ExprHologramLine.java +++ b/src/main/java/com/ankoki/skjade/hooks/holograms/expressions/ExprHologramLine.java @@ -14,7 +14,7 @@ import com.gmail.filoghost.holographicdisplays.api.Hologram; import com.gmail.filoghost.holographicdisplays.api.line.HologramLine; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; @Name("Hologram Line") @Description("The hologram line of a specified hologram") diff --git a/src/main/java/com/ankoki/skjade/hooks/protocollib/effects/EffRotatePlayer.java b/src/main/java/com/ankoki/skjade/hooks/protocollib/effects/EffRotatePlayer.java index 90659e2..2eab8af 100644 --- a/src/main/java/com/ankoki/skjade/hooks/protocollib/effects/EffRotatePlayer.java +++ b/src/main/java/com/ankoki/skjade/hooks/protocollib/effects/EffRotatePlayer.java @@ -12,7 +12,7 @@ import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.Event; -import org.eclipse.jdt.annotation.Nullable; +import org.jetbrains.annotations.Nullable; import java.lang.reflect.InvocationTargetException; import java.util.Arrays; diff --git a/src/main/java/com/ankoki/skjade/utils/NonLegacyClassInfo.java b/src/main/java/com/ankoki/skjade/utils/NonLegacyClassInfo.java index 9848be2..a945299 100644 --- a/src/main/java/com/ankoki/skjade/utils/NonLegacyClassInfo.java +++ b/src/main/java/com/ankoki/skjade/utils/NonLegacyClassInfo.java @@ -33,7 +33,6 @@ public String toVariableNameString(StructureType o) { return o.getName().toLowerCase().replace("_", " "); } - @Override public String getVariableNamePattern() { return "[a-z ]+"; } diff --git a/src/main/java/com/ankoki/skjade/utils/Version.java b/src/main/java/com/ankoki/skjade/utils/Version.java index cef7b4d..20cc5c8 100644 --- a/src/main/java/com/ankoki/skjade/utils/Version.java +++ b/src/main/java/com/ankoki/skjade/utils/Version.java @@ -1,32 +1,64 @@ package com.ankoki.skjade.utils; +import com.ankoki.skjade.SkJade; + public enum Version { - v1_7_R1(true), - v1_7_R2(true), - v1_7_R3(true), - v1_7_R4(true), - v1_8_R1(true), - v1_9_R1(true), - v1_10_R1(true), - v1_11_R1(true), - v1_12_R1(true), - v1_12_R2(true), - v1_13_R1(false), - v1_14_R1(false), - v1_15_R1(false), - v1_16_R1(false), - v1_16_R2(false), - v1_16_R3(false), - v1_16_R4(false), - v1_17_R1(false), - UNKNOWN(false); - - private final boolean legacy; - Version(boolean legacy) { - this.legacy = legacy; + + v1_7_R1(), + v1_7_R2(), + v1_7_R3(), + v1_7_R4(), + v1_8_R1(), + v1_9_R1(), + v1_10_R1(), + v1_11_R1(), + v1_12_R1(), + v1_12_R2(), + v1_13_R1(), + v1_14_R1(), + v1_15_R1(), + v1_16_R1(), + v1_16_R2(), + v1_16_R3(), + v1_16_R4(), + v1_17_R1(), + v1_18_R1(), + UNKNOWN(); + + + // Can't be final. + public static Version CURRENT_VERSION; + + static { + String packageName = SkJade.getInstance().getServer().getClass().getPackage().getName(); + String version = packageName.substring(packageName.lastIndexOf('.') + 1); + try { + CURRENT_VERSION = Version.valueOf(version); + } catch (IllegalArgumentException ex) { + CURRENT_VERSION = UNKNOWN; + System.err.println("You are using an unknown version (" + version + "). You could be using a version before 1.7, or a newer version I haven't supported."); + } + } + + public static boolean currentIsLegacy() { + return CURRENT_VERSION.legacy; } + private final boolean legacy = this.ordinal() < 10; + public boolean isLegacy() { return legacy; } + + public boolean isNewer() { + return this.ordinal() > CURRENT_VERSION.ordinal(); + } + + public boolean isOlder() { + return this.ordinal() < CURRENT_VERSION.ordinal(); + } + + public boolean equals(Version version) { + return this.ordinal() == version.ordinal(); + } }