commit 0dcb356c1d158138c5bc5b267f4a225e185328da Author: Xelara Networks Date: Sun Jun 7 23:58:50 2026 -0400 first commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..bc7706e --- /dev/null +++ b/pom.xml @@ -0,0 +1,47 @@ + + 4.0.0 + + com.bitnix + AntiFLY-PVP + 1.1 + jar + + AntiFLY-PVP + + + 21 + UTF-8 + + + + + papermc + https://repo.papermc.io/repository/maven-public/ + + + + + + io.papermc.paper + paper-api + 1.21.8-R0.1-SNAPSHOT + provided + + + + + AntiFLY-PVP + + + org.apache.maven.plugins + maven-compiler-plugin + 3.13.0 + + 21 + + + + + diff --git a/src/main/java/com/bitnix/antiflypvp/AntiFlyPVPPlugin.java b/src/main/java/com/bitnix/antiflypvp/AntiFlyPVPPlugin.java new file mode 100644 index 0000000..29a414b --- /dev/null +++ b/src/main/java/com/bitnix/antiflypvp/AntiFlyPVPPlugin.java @@ -0,0 +1,269 @@ +package com.bitnix.antiflypvp; + +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Projectile; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerToggleFlightEvent; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitTask; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public final class AntiFlyPVPPlugin extends JavaPlugin implements Listener { + + private final Map combatUntil = new HashMap<>(); + private final Map expiryTasks = new HashMap<>(); + + private long combatDurationTicks; + private long combatDurationMillis; + private boolean disableFlightOnAnyDamage; + private boolean disableFlightOnDamagingAnyEntity; + private boolean opBypass; + + private String msgCombatStartDamaged; + private String msgCombatStartAttack; + private String msgCombatFlyBlocked; + private String msgCombatEnded; + + @Override + public void onEnable() { + saveDefaultConfig(); + loadPluginSettings(); + + getServer().getPluginManager().registerEvents(this, this); + getLogger().info("AntiFLY-PVP enabled."); + } + + @Override + public void onDisable() { + for (BukkitTask task : expiryTasks.values()) { + if (task != null) { + task.cancel(); + } + } + expiryTasks.clear(); + combatUntil.clear(); + } + + private void loadPluginSettings() { + reloadConfig(); + FileConfiguration config = getConfig(); + + int seconds = config.getInt("combat-duration-seconds", 300); + if (seconds < 1) { + seconds = 300; + } + + this.combatDurationMillis = seconds * 1000L; + this.combatDurationTicks = seconds * 20L; + + this.disableFlightOnAnyDamage = config.getBoolean("disable-flight-on-any-damage", true); + this.disableFlightOnDamagingAnyEntity = config.getBoolean("disable-flight-on-damaging-any-entity", true); + this.opBypass = config.getBoolean("op-bypass", true); + + this.msgCombatStartDamaged = color(config.getString( + "messages.combat-start-damaged", + "&cFlight disabled: you were damaged and are now in combat for &e%time%&c seconds." + )); + + this.msgCombatStartAttack = color(config.getString( + "messages.combat-start-attack", + "&cFlight disabled: you attacked something and are now in combat for &e%time%&c seconds." + )); + + this.msgCombatFlyBlocked = color(config.getString( + "messages.combat-fly-blocked", + "&cYou cannot fly while in combat. Time left: &e%time%&c seconds." + )); + + this.msgCombatEnded = color(config.getString( + "messages.combat-ended", + "&aYour combat timer ended. You may fly again if you still have permission." + )); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onPlayerDamaged(EntityDamageEvent event) { + if (!disableFlightOnAnyDamage) { + return; + } + + if (!(event.getEntity() instanceof Player player)) { + return; + } + + if (shouldIgnore(player)) { + return; + } + + enterCombat(player, msgCombatStartDamaged); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onEntityDamagedByPlayer(EntityDamageByEntityEvent event) { + if (!disableFlightOnDamagingAnyEntity) { + return; + } + + Player attacker = getResponsiblePlayer(event.getDamager()); + if (attacker == null) { + return; + } + + if (shouldIgnore(attacker)) { + return; + } + + enterCombat(attacker, msgCombatStartAttack); + } + + @EventHandler(ignoreCancelled = true) + public void onFlightToggle(PlayerToggleFlightEvent event) { + Player player = event.getPlayer(); + + if (shouldIgnore(player)) { + return; + } + + if (!isInCombat(player.getUniqueId())) { + return; + } + + event.setCancelled(true); + disableFlightNow(player); + player.sendMessage(replaceTime(msgCombatFlyBlocked, getRemainingSeconds(player.getUniqueId()))); + } + + @EventHandler + public void onJoin(PlayerJoinEvent event) { + Player player = event.getPlayer(); + + if (shouldIgnore(player)) { + return; + } + + if (isInCombat(player.getUniqueId())) { + disableFlightNow(player); + } + } + + private Player getResponsiblePlayer(Entity damager) { + if (damager instanceof Player player) { + return player; + } + + if (damager instanceof Projectile projectile) { + Object shooter = projectile.getShooter(); + if (shooter instanceof Player player) { + return player; + } + } + + return null; + } + + private boolean shouldIgnore(Player player) { + if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) { + return true; + } + + return opBypass && player.isOp(); + } + + private void enterCombat(Player player, String startMessage) { + UUID uuid = player.getUniqueId(); + boolean alreadyInCombat = isInCombat(uuid); + + disableFlightNow(player); + + long expiresAt = System.currentTimeMillis() + combatDurationMillis; + combatUntil.put(uuid, expiresAt); + + BukkitTask oldTask = expiryTasks.remove(uuid); + if (oldTask != null) { + oldTask.cancel(); + } + + BukkitTask newTask = Bukkit.getScheduler().runTaskLater(this, () -> { + Long stored = combatUntil.get(uuid); + if (stored != null && stored <= System.currentTimeMillis()) { + combatUntil.remove(uuid); + expiryTasks.remove(uuid); + + Player online = Bukkit.getPlayer(uuid); + if (online != null && online.isOnline()) { + online.sendMessage(msgCombatEnded); + } + } + }, combatDurationTicks); + + expiryTasks.put(uuid, newTask); + + if (!alreadyInCombat) { + player.sendMessage(replaceTime(startMessage, combatDurationMillis / 1000L)); + } + } + + private void disableFlightNow(Player player) { + if (player.isFlying()) { + player.setFlying(false); + } + + if (player.getAllowFlight()) { + player.setAllowFlight(false); + } + } + + private boolean isInCombat(UUID uuid) { + Long expiresAt = combatUntil.get(uuid); + if (expiresAt == null) { + return false; + } + + if (expiresAt <= System.currentTimeMillis()) { + combatUntil.remove(uuid); + + BukkitTask task = expiryTasks.remove(uuid); + if (task != null) { + task.cancel(); + } + + return false; + } + + return true; + } + + private long getRemainingSeconds(UUID uuid) { + Long expiresAt = combatUntil.get(uuid); + if (expiresAt == null) { + return 0L; + } + + long remaining = expiresAt - System.currentTimeMillis(); + if (remaining <= 0L) { + return 0L; + } + + return (remaining + 999L) / 1000L; + } + + private String replaceTime(String message, long seconds) { + return message.replace("%time%", String.valueOf(seconds)); + } + + private String color(String input) { + return input == null ? "" : input.replace("&", "ยง"); + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..f40b264 --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1,12 @@ +combat-duration-seconds: 300 + +disable-flight-on-any-damage: true +disable-flight-on-damaging-any-entity: true + +op-bypass: true + +messages: + combat-start-damaged: "&cFlight disabled: you were damaged and are now in combat for &e%time%&c seconds." + combat-start-attack: "&cFlight disabled: you attacked something and are now in combat for &e%time%&c seconds." + combat-fly-blocked: "&cYou cannot fly while in combat. Time left: &e%time%&c seconds." + combat-ended: "&aYour combat timer ended. You may fly again if you still have permission." diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..72cb4d4 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,6 @@ +name: AntiFLY-PVP +version: 1.1 +main: com.bitnix.antiflypvp.AntiFlyPVPPlugin +api-version: '1.21' +author: bitnix +description: Disables player flight during combat. diff --git a/target/AntiFLY-PVP.jar b/target/AntiFLY-PVP.jar new file mode 100644 index 0000000..7089d0f Binary files /dev/null and b/target/AntiFLY-PVP.jar differ diff --git a/target/classes/com/bitnix/antiflypvp/AntiFlyPVPPlugin.class b/target/classes/com/bitnix/antiflypvp/AntiFlyPVPPlugin.class new file mode 100644 index 0000000..c17d7fb Binary files /dev/null and b/target/classes/com/bitnix/antiflypvp/AntiFlyPVPPlugin.class differ diff --git a/target/classes/config.yml b/target/classes/config.yml new file mode 100644 index 0000000..f40b264 --- /dev/null +++ b/target/classes/config.yml @@ -0,0 +1,12 @@ +combat-duration-seconds: 300 + +disable-flight-on-any-damage: true +disable-flight-on-damaging-any-entity: true + +op-bypass: true + +messages: + combat-start-damaged: "&cFlight disabled: you were damaged and are now in combat for &e%time%&c seconds." + combat-start-attack: "&cFlight disabled: you attacked something and are now in combat for &e%time%&c seconds." + combat-fly-blocked: "&cYou cannot fly while in combat. Time left: &e%time%&c seconds." + combat-ended: "&aYour combat timer ended. You may fly again if you still have permission." diff --git a/target/classes/plugin.yml b/target/classes/plugin.yml new file mode 100644 index 0000000..72cb4d4 --- /dev/null +++ b/target/classes/plugin.yml @@ -0,0 +1,6 @@ +name: AntiFLY-PVP +version: 1.1 +main: com.bitnix.antiflypvp.AntiFlyPVPPlugin +api-version: '1.21' +author: bitnix +description: Disables player flight during combat. diff --git a/target/maven-archiver/pom.properties b/target/maven-archiver/pom.properties new file mode 100644 index 0000000..cabdb46 --- /dev/null +++ b/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Sun Jun 07 20:39:31 EDT 2026 +artifactId=AntiFLY-PVP +groupId=com.bitnix +version=1.1 diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000..6bc3eca --- /dev/null +++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1 @@ +com/bitnix/antiflypvp/AntiFlyPVPPlugin.class diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000..e8e025e --- /dev/null +++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1 @@ +/home/bitnix/Desktop/AntiFLY-PVP/src/main/java/com/bitnix/antiflypvp/AntiFlyPVPPlugin.java