Skip to content
Open
7 changes: 7 additions & 0 deletions src/main/java/com/gmail/llmdlio/townyflight/TownyFlight.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.gmail.llmdlio.townyflight.config.Settings;
import com.gmail.llmdlio.townyflight.config.TownyFlightConfig;
import com.gmail.llmdlio.townyflight.integrations.TownyFlightPlaceholderExpansion;
import com.gmail.llmdlio.townyflight.listeners.EnemyEnterTownListener;
import com.gmail.llmdlio.townyflight.listeners.PlayerEnterTownListener;
import com.gmail.llmdlio.townyflight.listeners.PlayerFallListener;
import com.gmail.llmdlio.townyflight.listeners.PlayerJoinListener;
Expand Down Expand Up @@ -115,6 +116,10 @@ protected void registerEvents() {
pm.registerEvents(new TownStatusScreenListener(), this);
pm.registerEvents(new PlayerEnterTownListener(this), this);

if (!Settings.flightDisableBy.equals("NONE")) {
pm.registerEvents(new EnemyEnterTownListener(this, api), this);
}

if (Settings.disableCombatPrevention)
pm.registerEvents(new PlayerPVPListener(), this);
}
Expand All @@ -139,4 +144,6 @@ private static boolean isFoliaClassPresent() {
return false;
}
}


Comment on lines +147 to +148
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unneeded diff

}
114 changes: 103 additions & 11 deletions src/main/java/com/gmail/llmdlio/townyflight/TownyFlightAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@ public class TownyFlightAPI {
public Set<Player> fallProtectedPlayers = ConcurrentHashMap.newKeySet();
private static Map<UUID, Boolean> canFlyCache = new ConcurrentHashMap<>();
private static NamespacedKey forceAllowFlight;
private static Map<UUID, Integer> enemiesInTown = new ConcurrentHashMap<>();

public TownyFlightAPI(TownyFlight plugin) {
TownyFlightAPI.plugin = plugin;
forceAllowFlight = new NamespacedKey(plugin, "force_allow_flight");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unneeded diff.

}

public static TownyFlightAPI getInstance() {
Expand All @@ -52,15 +54,18 @@ public static TownyFlightAPI getInstance() {
* @return true if the {@link Player} is allowed to fly.
**/
public boolean canFly(Player player, boolean silent) {

// Get the town the player is currently standing in
Town town = TownyAPI.getInstance().getTown(player.getLocation());

//
Comment on lines +60 to +61
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unneeded diff.

if (player.hasPermission("townyflight.bypass")
|| player.getGameMode().equals(GameMode.SPECTATOR)
|| player.getGameMode().equals(GameMode.CREATIVE)
|| town != null && MetaData.getFreeFlightMeta(town)
|| getForceAllowFlight(player))
return true;

if (!Permission.has(player, "townyflight.command.tfly", silent)) return false;
if (!Permission.has(player, "townyflight.command.tfly", true)) return false;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably an unneeded diff, we've also lost the silent permission test.


Resident resident = TownyUniverse.getInstance().getResident(player.getUniqueId());
if (resident == null) return false;
Expand All @@ -79,6 +84,12 @@ public boolean canFly(Player player, boolean silent) {
if (!silent) Message.of("notInTownMsg").to(player);
return false;
}

// If the enemiesInTown hashmap contains this town and its value is >0, players cannot fly there.
if(containsTown(town)){
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if(containsTown(town)){
if (townHasEnemiesPresent(town.getUUID())) {

return false;
}

return true;
}

Expand Down Expand Up @@ -140,8 +151,9 @@ public void removeFlight(Player player, boolean silent, boolean forced, String c
if (!silent) {
if (forced) {
String reason = Message.getLangString("flightDeactivatedMsg");
if (cause == "pvp") reason = Message.getLangString("flightDeactivatedPVPMsg");
if (cause == "console") reason = Message.getLangString("flightDeactivatedConsoleMsg");
if (cause.equals("pvp")) reason = Message.getLangString("flightDeactivatedPVPMsg");
if (cause.equals("console")) reason = Message.getLangString("flightDeactivatedConsoleMsg");
if (cause.equals("enemynearby")) reason = Message.getLangString("flightDeactivatedEnemyNearbyMsg");
Comment on lines +154 to +156
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unneeded change. Strings always == themselves in Java.

Message.of(reason + Message.getLangString("flightOffMsg")).to(player);
} else {
Message.of("flightOffMsg").to(player);
Expand All @@ -165,9 +177,12 @@ public void removeFlight(Player player, boolean silent, boolean forced, String c
* @param silent true will mean no message is shown to the {@link Player}.
*/
public void addFlight(Player player, boolean silent) {
if (!silent) Message.of("flightOnMsg").to(player);
player.setAllowFlight(true);
cachePlayerFlight(player, true);
// Added a canFly check
if(canFly(player, true)){
if (!silent) Message.of("flightOnMsg").to(player);
player.setAllowFlight(true);
cachePlayerFlight(player, true);
}
Comment on lines +180 to +185
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is not meant to test if a player can fly, it is meant to only give flight.

If you're calling this method in new code, that new method should confirm the player can fly before calling this addFlight method.

}

/**
Expand Down Expand Up @@ -199,19 +214,50 @@ public void testForFlight(Player player, boolean silent) {
* and are not given a flight bypass of some kind, remove their flight. Called when
* a town has their free flight disabled.
*/
public void takeFlightFromPlayersInTown(Town town) {
public static void takeFlightFromPlayersInTown(Town town, String cause) {
for (final Player player : new ArrayList<>(Bukkit.getOnlinePlayers())) {
if (player.hasPermission("townyflight.bypass")


if ((player.hasPermission("townyflight.bypass") || !player.getAllowFlight()
Comment on lines +219 to +221
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unneeded diff.

|| !player.getAllowFlight()
|| TownyAPI.getInstance().isWilderness(player.getLocation())
|| !TownyAPI.getInstance().getTown(player.getLocation()).equals(town)
|| TownyFlightAPI.getInstance().canFly(player, true))
|| TownyFlightAPI.getInstance().canFly(player, true)))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unneeded diff.

continue;

TownyFlightAPI.getInstance().removeFlight(player, false, true, "");
TownyFlightAPI.getInstance().removeFlight(player, false, true, cause);
}
}

/**
* Parse over the players online in the server and if they're in the given {@link Town},
* Check if they can fly, and then add flight to them.
*/
public static void addFlightToPlayersInTown(Town town){
for (final Player player : new ArrayList<>(Bukkit.getOnlinePlayers())) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of Bukkit.getOnlinePlayer() you can use the TownyAPI method for getting online player in a single town.

// If the player's town does not match the flight re-adding, dont add it.
if(TownyAPI.getInstance().getTown(player) != town) {
return;
}
Comment on lines +238 to +241
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't be required any longer.


// If they can already fly, dont add it
if (player.getAllowFlight()) return;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (player.getAllowFlight()) return;
if (player.getAllowFlight()) continue;



plugin.getScheduler().runLater(player, () -> {
if (!TownyFlightAPI.getInstance().canFly(player, true)){
return;
}
if (Settings.autoEnableFlight) {
TownyFlightAPI.getInstance().addFlight(player, Settings.autoEnableSilent);
}

TownyFlightAPI.cachePlayerFlight(player, true);
}, 1);

}
}

/**
* This method allows the player to fly everywhere, even if they are not in a town. Useful for
* plugins that have items that can make you fly.
Expand Down Expand Up @@ -262,4 +308,50 @@ public static void cachePlayerFlight(Player player, boolean canFly) {
public static void removeCachedPlayer(Player player) {
canFlyCache.remove(player.getUniqueId());
}

// Increments the enemiesInTown counter hashmap for the given town.
public static void incrementEnemiesInTown(Town town) {

UUID uuid = town.getUUID();

if(enemiesInTown.containsKey(uuid)){
enemiesInTown.put(uuid, enemiesInTown.get(uuid) + 1);
}
else{
enemiesInTown.put(uuid, 1);
}
takeFlightFromPlayersInTown(town, "enemynearby");

}

// Decrements the enemiesInTown counter hashmap for the given town.
public static void decrementEnemiesInTown(Town town) {

UUID uuid = town.getUUID();

if(enemiesInTown.containsKey(uuid)){
enemiesInTown.put(uuid, enemiesInTown.get(uuid) - 1);

// Re-add flight if there are no more enemies in town.
if(enemiesInTown.get(uuid) <= 0){
addFlightToPlayersInTown(town);
}
}
else{
plugin.getServer().getLogger().severe("Tried to decrement enemies in town for a town that shouldn't have any enemies.");
}
}

// Returns true if the hashmap contains the supplied town and the value is >0.
public static boolean containsTown(Town town) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method should accept a UUID instead of the whole Town.

Suggested change
public static boolean containsTown(Town town) {
public static boolean townHasEnemiesPresent(UUID uuid) {


UUID uuid = town.getUUID();

if(enemiesInTown.containsKey(uuid) && enemiesInTown.get(uuid) > 0){
return true;
}
else{
return false;
}
Comment on lines +348 to +355
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
UUID uuid = town.getUUID();
if(enemiesInTown.containsKey(uuid) && enemiesInTown.get(uuid) > 0){
return true;
}
else{
return false;
}
return enemiesInTown.containsKey(uuid) && enemiesInTown.get(uuid) > 0;

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ private void parseTownCommand(String[] args) {
MetaData.setFreeFlightMeta(town, futurestate);
Message.of(String.format(Message.getLangString("townWideFlight"), Message.getLangString(futurestate? "enabled" : "disabled"), town)).to(sender);
if (!futurestate)
TownyFlightAPI.getInstance().takeFlightFromPlayersInTown(town);
TownyFlightAPI.getInstance().takeFlightFromPlayersInTown(town, "");
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ public enum ConfigNodes {
"Entering PVP combat. ",
"",
"# Message shown when a player has flight taken away because of PVP."),
LANG_FLIGHTDEACTIVATEDENEMYNEARBYMSG(
"language.flightDeactivatedEnemyNearbyMsg",
"Flight has been disabled due to a player entering your town. ",
"",
"# Message shown when a player has flight taken away because of a player entering their town."),
LANG_FLIGHTDEACTIVATEDCONSOLEMSG(
"language.flightDeactivatedConsoleMsg",
"Flight priviledges removed. ",
Expand Down Expand Up @@ -129,7 +134,16 @@ public enum ConfigNodes {
"options.flight_Disable_Timer",
"3",
"",
"# Number of seconds after leaving an allowed flight area before flight is taken away.", "# Set to 0 to take flight away immediately.");
"# Number of seconds after leaving an allowed flight area before flight is taken away.", "# Set to 0 to take flight away immediately."),
OPTIONS_DISABLE_BY(
"options.flight_Disable_By",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be renamed to something like flight_Disabled_By_Outsider

"NONE",
"",
"# If set to NONE, flight will not be disabled on players entering a claim.",
"# If set to ALLY, flight will be disabled by ALLIES, NEUTRAL and ENEMY players entering a claim.",
"# If set to NEUTRAL, flight will be disabled on NEUTRAL and ENEMY players entering a claim",
"# If set to ENEMY, flight will be disabled only when ENEMY players enter a claim",
"# Valid inputs: NONE, ALLY, NEUTRAL, ENEMY.");

private final String Root;
private final String Default;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ public class Settings {
public static Boolean showPermissionInMessage;
public static Boolean siegeWarFound;
public static int flightDisableTimer;
public static String flightDisableBy;
public static int flightReenableTimer;
private static Map<String, String> lang = new HashMap<String,String>();

public static boolean loadSettings(TownyFlightConfig _config) {
Expand All @@ -32,6 +34,7 @@ private static void loadOptions() {
disableCombatPrevention = Boolean.valueOf(getOption("disable_Combat_Prevention"));
showPermissionInMessage = Boolean.valueOf(getOption("show_Permission_After_No_Permission_Message"));
flightDisableTimer = Integer.valueOf(getOption("flight_Disable_Timer"));
flightDisableBy = String.valueOf(getOption("flight_Disable_By"));
}

public static void loadStrings() {
Expand All @@ -43,6 +46,7 @@ public static void loadStrings() {
lang.put("notInTownMsg", getString("notInTownMsg"));
lang.put("flightDeactivatedMsg", getString("flightDeactivatedMsg"));
lang.put("flightDeactivatedPVPMsg", getString("flightDeactivatedPVPMsg"));
lang.put("flightDeactivatedEnemyNearbyMsg", getString("flightDeactivatedEnemyNearbyMsg"));
lang.put("flightDeactivatedConsoleMsg", getString("flightDeactivatedConsoleMsg"));
lang.put("noPermission", getString("noPermission"));
lang.put("missingNode", getString("missingNode"));
Expand Down
Loading