Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public class TownyFlightCommand implements TabExecutor {
private TownyFlight plugin;
private CommandSender sender;
private static final List<String> tflyTabCompletes = Arrays.asList(
"reload","tempflight","town","help","?"
"reload","tempflight","pay","town","help","?"
);

public TownyFlightCommand(TownyFlight plugin) {
Expand All @@ -57,6 +57,12 @@ public List<String> onTabComplete(CommandSender sender, Command command, String
if (args.length == 3)
return Collections.singletonList("toggleflight");
break;
case "pay":
if (args.length == 2)
return getTownyStartingWith(args[1], "r");
if (args.length == 3)
return NameUtil.filterByStart(Arrays.asList("10", "1000s", "60m", "1h", "1d"), args[2]);
break;
default:
if (args.length == 1)
return filterByStartOrGetTownyStartingWith(tflyTabCompletes, args[0], "r");
Expand Down Expand Up @@ -104,6 +110,8 @@ private void parseCommand(String[] args) {
} else if (args[0].equalsIgnoreCase("reload") && Permission.has(sender,"townyflight.command.tfly.reload", false)) {
// We have /tfly reload and tested for permission node.
reloadPlugin();
} else if (args[0].equalsIgnoreCase("pay") && Permission.has(sender, "townyflight.command.tfly.pay", false)) {
parseTempFlightPaymentCommand(StringMgmt.remFirstArg(args));
} else if (args[0].equalsIgnoreCase("tempflight") && Permission.has(sender,"townyflight.command.tfly.tempflight", false)) {
// We have /tfly tempflight and tested for permission node.
parseTempFlightCommand(StringMgmt.remFirstArg(args));
Expand Down Expand Up @@ -172,6 +180,71 @@ private void parseTempFlightCommand(String[] args) {

}

private void parseTempFlightPaymentCommand(String[] args) {
Player senderPlayer = (Player) sender;

if (!Settings.allowTempFlightPayments) {
Message.of(Message.getLangString("tempFlightPaymentsDisabled")).to(sender);
return;
}

if (args.length < 2) {
showTflyHelp();
return;
}

String recipientName = args[0];
Resident recipientResident = TownyAPI.getInstance().getResident(recipientName);

if (recipientResident == null || !recipientResident.hasUUID()) {
Message.of("Player " + recipientName + " not found. Could not transfer tempflight.").to(sender);
return;
}

UUID recipientUUID = recipientResident.getUUID();

if (senderPlayer.getUniqueId().equals(recipientUUID)) {
Message.of(Message.getLangString("tempFlightPaymentSelf")).to(sender);
return;
}

long seconds = parseSeconds(args[1]);
if (seconds <= 0L) {
Message.of(Message.getLangString("tempFlightPaymentInvalid")).to(sender);
return;
}

if (TempFlightTask.getSeconds(senderPlayer.getUniqueId()) < seconds) {
Message.of(Message.getLangString("tempFlightPaymentInsufficient")).to(sender);
return;
}

if (!TempFlightTask.transferPlayerTempFlightSeconds(senderPlayer.getUniqueId(), recipientUUID, seconds)) {
Message.of(Message.getLangString("tempFlightPaymentFailed")).to(sender);
return;
}

String formattedTimeValue = TimeMgmt.getFormattedTimeValue(seconds * 1000L);
Message.of(String.format(
Message.getLangString("tempFlightPaymentSent"),
formattedTimeValue,
recipientName
)).to(sender);

if (recipientResident.isOnline()) {
Player recipientPlayer = recipientResident.getPlayer();

Message.of(String.format(
Message.getLangString("tempFlightPaymentReceived"),
formattedTimeValue,
senderPlayer.getName()
)).to(recipientPlayer);

if (Settings.autoEnableFlight && TownyFlightAPI.getInstance().canFly(recipientPlayer, true))
TownyFlightAPI.getInstance().addFlight(recipientPlayer, Settings.autoEnableSilent);
}
}

private long parseSeconds(String string) {
if (string.endsWith("s") || string.endsWith("m") || string.endsWith("h") || string.endsWith("d"))
return TimeTools.getSeconds(string);
Expand Down Expand Up @@ -227,6 +300,8 @@ private void showTflyHelp() {
Message.of(Colors.WHITE + "/tfly [playername] - Toggle flight for a player.").to(sender);
if (Permission.has(sender, "townyflight.command.tfly.town", true))
Message.of(Colors.WHITE + "/tfly town [townname] toggleflight - Toggle free flight in the given town.").to(sender);
if (Permission.has(sender, "townyflight.command.tfly.pay", true))
Message.of(Colors.WHITE + "/tfly pay [playername] [time] - Transfer tempflight time to another player.").to(sender);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,42 @@ public enum ConfigNodes {
"Your tempflight priviledges have expired.",
"",
"# The message shown to the player when they run out of temp flight."),
LANG_TEMPFLIGHTPAYMENTSDISABLED(
"language.tempFlightPaymentsDisabled",
"Tempflight payments are disabled.",
"",
"# Message shown when a player attempts to transfer tempflight while payments are disabled."),
LANG_TEMPFLIGHTPAYMENTSELF(
"language.tempFlightPaymentSelf",
"You cannot transfer tempflight time to yourself.",
"",
"# Message shown when a player attempts to transfer tempflight to themselves."),
LANG_TEMPFLIGHTPAYMENTINSUFFICIENT(
"language.tempFlightPaymentInsufficient",
"You do not have enough tempflight time to make that payment.",
"",
"# Message shown when a player does not have enough tempflight time to transfer."),
LANG_TEMPFLIGHTPAYMENTSENT(
"language.tempFlightPaymentSent",
"You transferred %s of tempflight time to %s.",
"",
"# Message shown to a player after successfully transferring tempflight time."),
LANG_TEMPFLIGHTPAYMENTRECEIVED(
"language.tempFlightPaymentReceived",
"You received %s of tempflight time from %s.",
"",
"# Message shown to an online player after receiving tempflight time."),
LANG_TEMPFLIGHTPAYMENTINVALID(
"language.tempFlightPaymentInvalid",
"You must transfer more than 0 seconds of tempflight time.",
"",
"# Message shown when a player attempts to transfer an invalid amount."),
LANG_TEMPFLIGHTPAYMENTFAILED(
"language.tempFlightPaymentFailed",
"The tempflight payment could not be completed.",
"",
"# Message shown when a tempflight payment fails unexpectedly."),


OPTIONS("options", "", "",
"#################",
"# Options #",
Expand Down Expand Up @@ -167,6 +201,11 @@ public enum ConfigNodes {
"owntown,nationtowns",
"",
"# The list of areas which allow tempflight, allowed words: owntown, nationtowns, alliedtowns, alltowns, trustedtowns, wilderness"),
OPTIONS_TEMPFLIGHT_ALLOW_PAYMENTS(
"options.allow_tempflight_payments",
"false",
"",
"# When true, players with the townyflight.command.tfly.pay permission can transfer tempflight time to other players."),
OPTIONS_MESSAGES_DESTINATION(
"options.messages_appear_in",
"chat",
Expand Down
11 changes: 10 additions & 1 deletion src/main/java/com/gmail/llmdlio/townyflight/config/Settings.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ public class Settings {
public static Boolean disableCombatPrevention;
public static Boolean disableDuringWar;
public static Boolean showPermissionInMessage;
public static Boolean showTempFlightTimeRemainingInActionBar;
public static Boolean showTempFlightTimeRemainingInActionBar;
public static Boolean allowTempFlightPayments;
public static Boolean siegeWarFound;
public static boolean essentialsFound;
public static MessageLocation messageLocation;
Expand All @@ -41,6 +42,7 @@ private static void loadOptions() {
flightDisableTimer = Integer.valueOf(getOption("flight_Disable_Timer"));
showTempFlightTimeRemainingInActionBar = Boolean.valueOf(getOption("show_tempflight_time_remaining_in_actionbar"));
pauseTempFlightTimeWhileEssentialsAFK = Boolean.valueOf(getOption("pause_tempflight_time_while_afk"));
allowTempFlightPayments = Boolean.valueOf(getOption("allow_tempflight_payments"));
allowedTempFlightAreas = allowedTempFlightAreas();
messageLocation = getMessageLocation();
returnToTownMessageAppearsInTitle = Boolean.valueOf(getOption("returnToAllowedArea_appears_in_title_message_override"));
Expand Down Expand Up @@ -72,6 +74,13 @@ public static void loadStrings() {
lang.put("youHaveReceivedTempFlight", getString("youHaveReceivedTempFlight"));
lang.put("yourTempFlightHasExpired", getString("yourTempFlightHasExpired"));
lang.put("tempFlightTimeRemainging", getString("tempFlightTimeRemainging"));
lang.put("tempFlightPaymentsDisabled", getString("tempFlightPaymentsDisabled"));
lang.put("tempFlightPaymentSelf", getString("tempFlightPaymentSelf"));
lang.put("tempFlightPaymentInsufficient", getString("tempFlightPaymentInsufficient"));
lang.put("tempFlightPaymentSent", getString("tempFlightPaymentSent"));
lang.put("tempFlightPaymentReceived", getString("tempFlightPaymentReceived"));
lang.put("tempFlightPaymentInvalid", getString("tempFlightPaymentInvalid"));
lang.put("tempFlightPaymentFailed", getString("tempFlightPaymentFailed"));
}

public static String getLangString(String languageString) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,44 @@ public static long getSeconds(UUID uuid) {
return playerUUIDSecondsMap.containsKey(uuid) ? playerUUIDSecondsMap.get(uuid) : 0L;
}

public static boolean transferPlayerTempFlightSeconds(UUID senderUUID, UUID recipientUUID, long seconds) {
if (seconds <= 0L || senderUUID.equals(recipientUUID))
return false;

Resident senderResident = TownyAPI.getInstance().getResident(senderUUID);
Resident recipientResident = TownyAPI.getInstance().getResident(recipientUUID);
if (senderResident == null || recipientResident == null)
return false;

long senderSeconds = playerUUIDSecondsMap.containsKey(senderUUID)
? playerUUIDSecondsMap.get(senderUUID)
: MetaData.getSeconds(senderUUID);

if (senderSeconds < seconds)
return false;

long recipientSeconds = playerUUIDSecondsMap.containsKey(recipientUUID)
? playerUUIDSecondsMap.get(recipientUUID)
: MetaData.getSeconds(recipientUUID);

if (recipientSeconds > Long.MAX_VALUE - seconds)
return false;

long senderRemainingSeconds = senderSeconds - seconds;
long recipientTotalSeconds = recipientSeconds + seconds;

MetaData.setSeconds(senderResident, senderRemainingSeconds, true);
MetaData.setSeconds(recipientResident, recipientTotalSeconds, true);

if (senderResident.isOnline())
playerUUIDSecondsMap.put(senderUUID, senderRemainingSeconds);

if (recipientResident.isOnline())
playerUUIDSecondsMap.put(recipientUUID, recipientTotalSeconds);

return true;
}

public static void addPlayerTempFlightSeconds(UUID uuid, long seconds) {
long existingSeconds = playerUUIDSecondsMap.containsKey(uuid) ? playerUUIDSecondsMap.get(uuid) : 0L;
playerUUIDSecondsMap.put(uuid, existingSeconds + seconds);
Expand Down
4 changes: 3 additions & 1 deletion src/main/resources/plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ permissions:
townyflight.command.tfly.tempflight:
description: User is able to grant tempflight to players.
default: op
townyflight.command.tfly.pay:
description: User is able to transfer their tempflight time to another player.
default: true
townyflight.command.tfly.other:
description: User is able to remove flight from other players.
default: op
Expand All @@ -49,5 +52,4 @@ permissions:
default: op
townyflight.wilderness:
description: Allows players to use /townyflight in the wilderness.

default: op