diff --git a/pom.xml b/pom.xml index 12563e6..4561c72 100644 --- a/pom.xml +++ b/pom.xml @@ -6,13 +6,13 @@ com.artillexstudios AxGraves - 1.11.2 + 1.12.0 jar AxGraves - 1.8 + 17 UTF-8 @@ -23,8 +23,8 @@ maven-compiler-plugin 3.8.1 - 15 - 15 + 17 + 17 -parameters @@ -106,7 +106,7 @@ com.artillexstudios.axapi axapi - 1.4.242 + 1.4.259 compile all diff --git a/src/main/java/com/artillexstudios/axgraves/AxGraves.java b/src/main/java/com/artillexstudios/axgraves/AxGraves.java index f885819..057492a 100644 --- a/src/main/java/com/artillexstudios/axgraves/AxGraves.java +++ b/src/main/java/com/artillexstudios/axgraves/AxGraves.java @@ -8,7 +8,7 @@ import com.artillexstudios.axapi.libs.boostedyaml.boostedyaml.settings.loader.LoaderSettings; import com.artillexstudios.axapi.libs.boostedyaml.boostedyaml.settings.updater.UpdaterSettings; import com.artillexstudios.axapi.nms.NMSHandlers; -import com.artillexstudios.axapi.utils.FastFieldAccessor; +import com.artillexstudios.axapi.reflection.FastFieldAccessor; import com.artillexstudios.axapi.utils.FeatureFlags; import com.artillexstudios.axapi.utils.MessageUtils; import com.artillexstudios.axgraves.commands.Commands; @@ -17,6 +17,7 @@ import com.artillexstudios.axgraves.listeners.DeathListener; import com.artillexstudios.axgraves.listeners.PlayerInteractListener; import com.artillexstudios.axgraves.schedulers.TickGraves; +import com.artillexstudios.axgraves.utils.UpdateNotifier; import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; import org.bukkit.Warning; @@ -65,6 +66,8 @@ public void enable() { } TickGraves.start(); + + if (CONFIG.getBoolean("update-notifier.enabled", true)) new UpdateNotifier(this, 5076); } public void disable() { diff --git a/src/main/java/com/artillexstudios/axgraves/grave/Grave.java b/src/main/java/com/artillexstudios/axgraves/grave/Grave.java index ccf5e77..9426056 100644 --- a/src/main/java/com/artillexstudios/axgraves/grave/Grave.java +++ b/src/main/java/com/artillexstudios/axgraves/grave/Grave.java @@ -1,9 +1,11 @@ package com.artillexstudios.axgraves.grave; -import com.artillexstudios.axapi.entity.PacketEntityFactory; -import com.artillexstudios.axapi.entity.impl.PacketArmorStand; import com.artillexstudios.axapi.hologram.Hologram; import com.artillexstudios.axapi.hologram.HologramLine; +import com.artillexstudios.axapi.items.WrappedItemStack; +import com.artillexstudios.axapi.nms.NMSHandlers; +import com.artillexstudios.axapi.packetentity.PacketEntity; +import com.artillexstudios.axapi.packetentity.meta.entity.ArmorStandMeta; import com.artillexstudios.axapi.scheduler.Scheduler; import com.artillexstudios.axapi.serializers.Serializers; import com.artillexstudios.axapi.utils.EquipmentSlot; @@ -51,7 +53,7 @@ public class Grave { private final String playerName; private final StorageGui gui; private int storedXP; - private PacketArmorStand entity; + private PacketEntity entity; private Hologram hologram; private boolean removed = false; @@ -98,21 +100,23 @@ public Grave(Location loc, @NotNull Player player, @NotNull ItemStack[] itemsAr, return; } - entity = (PacketArmorStand) PacketEntityFactory.get().spawnEntity(location.clone().add(0, CONFIG.getFloat("head-height", -1.2f), 0), EntityType.ARMOR_STAND); - entity.setItem(EquipmentSlot.HELMET, Utils.getPlayerHead(player)); - entity.setSmall(true); - entity.setInvisible(true); - entity.setHasBasePlate(false); + entity = NMSHandlers.getNmsHandler().createEntity(EntityType.ARMOR_STAND, location.clone().add(0, CONFIG.getFloat("head-height", -1.2f), 0)); + entity.setItem(EquipmentSlot.HELMET, WrappedItemStack.wrap(Utils.getPlayerHead(player))); + final ArmorStandMeta meta = (ArmorStandMeta) entity.meta(); + meta.small(true); + meta.invisible(true); + meta.setNoBasePlate(false); + entity.spawn(); if (CONFIG.getBoolean("rotate-head-360", true)) { - entity.getLocation().setYaw(player.getLocation().getYaw()); - entity.teleport(entity.getLocation()); + entity.location().setYaw(player.getLocation().getYaw()); + entity.teleport(entity.location()); } else { - entity.getLocation().setYaw(LocationUtils.getNearestDirection(player.getLocation().getYaw())); - entity.teleport(entity.getLocation()); + entity.location().setYaw(LocationUtils.getNearestDirection(player.getLocation().getYaw())); + entity.teleport(entity.location()); } - entity.onClick(event -> Scheduler.get().run(task -> interact(event.getPlayer(), event.getHand()))); + entity.onInteract(event -> Scheduler.get().run(task -> interact(event.getPlayer(), event.getHand()))); hologram = new Hologram(location.clone().add(0, CONFIG.getFloat("hologram-height", 1.2f), 0), Serializers.LOCATION.serialize(location), 0.3); @@ -143,8 +147,8 @@ public void update() { } if (CONFIG.getBoolean("auto-rotation.enabled", false)) { - entity.getLocation().setYaw(entity.getLocation().getYaw() + CONFIG.getFloat("auto-rotation.speed", 10f)); - entity.teleport(entity.getLocation()); + entity.location().setYaw(entity.location().getYaw() + CONFIG.getFloat("auto-rotation.speed", 10f)); + entity.teleport(entity.location()); } } public void interact(@NotNull Player opener, org.bukkit.inventory.EquipmentSlot slot) { @@ -298,7 +302,7 @@ public int getStoredXP() { return storedXP; } - public PacketArmorStand getEntity() { + public PacketEntity getEntity() { return entity; } diff --git a/src/main/java/com/artillexstudios/axgraves/utils/UpdateNotifier.java b/src/main/java/com/artillexstudios/axgraves/utils/UpdateNotifier.java new file mode 100644 index 0000000..b2b2339 --- /dev/null +++ b/src/main/java/com/artillexstudios/axgraves/utils/UpdateNotifier.java @@ -0,0 +1,101 @@ +package com.artillexstudios.axgraves.utils; + +import com.artillexstudios.axapi.AxPlugin; +import com.artillexstudios.axapi.scheduler.Scheduler; +import com.artillexstudios.axapi.utils.NumberUtils; +import com.artillexstudios.axapi.utils.StringUtils; +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.jetbrains.annotations.Nullable; + +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; +import java.util.HashMap; + +import static com.artillexstudios.axgraves.AxGraves.CONFIG; +import static com.artillexstudios.axgraves.AxGraves.MESSAGES; +import static java.time.temporal.ChronoUnit.SECONDS; + +public class UpdateNotifier implements Listener { + private final int id; + private final String current; + private final AxPlugin instance; + private String latest = null; + private boolean newest = true; + + public UpdateNotifier(AxPlugin instance, int id) { + this.id = id; + this.current = instance.getDescription().getVersion(); + this.instance = instance; + + instance.getServer().getPluginManager().registerEvents(this, instance); + + long time = 30L * 60L * 20L; + Scheduler.get().runAsyncTimer(t -> { + this.latest = readVersion(); + this.newest = isLatest(current); + + if (latest == null || newest) return; + Bukkit.getConsoleSender().sendMessage(getMessage()); + t.cancel(); + }, 50L, time); + } + + @EventHandler + public void onJoin(PlayerJoinEvent event) { + if (latest == null || newest) return; + if (!CONFIG.getBoolean("update-notifier.on-join", true)) return; + if (!event.getPlayer().hasPermission(instance.getName().toLowerCase() + ".update-notify")) return; + Scheduler.get().runLaterAsync(t -> { + event.getPlayer().sendMessage(getMessage()); + }, 50L); + } + + private String getMessage() { + HashMap map = new HashMap<>(); + map.put("%current%", current); + map.put("%latest%", latest); + return StringUtils.formatToString(CONFIG.getString("prefix") + MESSAGES.getString("update-notifier"), map); + } + + @Nullable + private String readVersion() { + try { + final HttpClient client = HttpClient.newHttpClient(); + final HttpRequest request = HttpRequest.newBuilder() + .uri(new URI("https://api.polymart.org/v1/getResourceInfoSimple/?resource_id=" + id + "&key=version")) + .timeout(Duration.of(10, SECONDS)) + .GET() + .build(); + + final HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + return response.body().toString(); + } catch (Exception ex) { + return null; + } + } + + public String getLatest() { + return latest; + } + + public boolean isLatest(String current) { + return getWeight(latest) <= getWeight(current); + } + + private int getWeight(String version) { + if (version == null) return 0; + String[] s = version.split("\\."); + if (!NumberUtils.isInt(s[0]) || !NumberUtils.isInt(s[1]) || !NumberUtils.isInt(s[2])) return 0; + int res = 0; + res += Integer.parseInt(s[0]) * 1000000; + res += Integer.parseInt(s[1]) * 1000; + res += Integer.parseInt(s[2]); + return res; + } +} \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index b8e9d1a..1d7575b 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -98,5 +98,12 @@ blacklisted-items: material: "barrier" name-contains: "Banned item's name" +# should be plugin notify you if there is a new update? +update-notifier: + # if enabled, it will display the message in the console + enabled: true + # if enabled, it will broadcast the update message to all players who have the .update-notify permission + on-join: true + # do not edit -version: 10 \ No newline at end of file +version: 11 \ No newline at end of file diff --git a/src/main/resources/messages.yml b/src/main/resources/messages.yml index a8b2de4..4c8ac55 100644 --- a/src/main/resources/messages.yml +++ b/src/main/resources/messages.yml @@ -28,5 +28,7 @@ grave-list: grave: "&#FFAAFF%player% &7- &#FFAAFF%world% %x%, %y%, %z% &7(%time%)" no-graves: "&#FFAAFFThere are no graves!" +update-notifier: "&#FF00FFThere is a new version of the plugin available! &#DDDDDD(&#FFFFFFcurrent: &#FF0000%current% &#DDDDDD| &#FFFFFFlatest: �FF00%latest%&#DDDDDD)" + # do not edit -version: 3 \ No newline at end of file +version: 4 \ No newline at end of file