Adds a delayed sign removed check #13

This commit adds a delayed check for whether the block at the sign change event's location is still a sign. If it isn't, it's assumed that a plugin blocked the sign creation by destroying the sign. In this case, the player is immediately refunded, even if refunds are disabled.
This commit is contained in:
Kristian Knarvik 2022-11-08 12:53:26 +01:00
parent 5c095e79f6
commit 4fee628469
3 changed files with 27 additions and 6 deletions

View File

@ -94,7 +94,7 @@ public class SignBreakListener implements Listener {
private void removeTrackedSign(Block block, boolean refund) {
if (block.getState() instanceof Sign) {
try {
TrackedSignManager.removeTrackedSign(block.getLocation(), refund);
TrackedSignManager.removeTrackedSign(block.getLocation(), refund, false);
} catch (IOException ignored) {
}
}

View File

@ -7,6 +7,9 @@ import net.knarcraft.paidsigns.container.PaidSignConditionMatch;
import net.knarcraft.paidsigns.formatting.PaidSignsTranslatableMessage;
import net.knarcraft.paidsigns.manager.EconomyManager;
import net.knarcraft.paidsigns.manager.TrackedSignManager;
import org.bukkit.Bukkit;
import org.bukkit.block.Block;
import org.bukkit.block.data.type.Sign;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@ -18,6 +21,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
/**
* A listener for listening to registered paid signs
@ -116,6 +120,21 @@ public class SignListener implements Listener {
}
performPaidSignTransaction(paidSign, player, event);
if (!event.isCancelled()) {
//Immediately refund if a plugin destroyed the sign within 5 ticks of the creation
Bukkit.getScheduler().scheduleSyncDelayedTask(PaidSigns.getInstance(), () -> {
Block block = event.getBlock();
if (!(block.getBlockData() instanceof Sign)) {
try {
TrackedSignManager.removeTrackedSign(block.getLocation(), true, true);
} catch (IOException e) {
PaidSigns.getInstance().getLogger().log(Level.WARNING, String.format("Unable to save changes " +
"about removed tracked sign at %s", block.getLocation()));
}
}
}, 5);
}
}
/**

View File

@ -48,16 +48,17 @@ public final class TrackedSignManager {
*
* @param signLocation <p>The location the sign was removed from</p>
* @param refund <p>Whether to perform a refund after un-tracking the sign</p>
* @param forceRefund <p>Whether to force a refund, even if refunding is disabled</p>
* @throws IOException <p>If unable to save the tracked signs</p>
*/
public static void removeTrackedSign(Location signLocation, boolean refund) throws IOException {
public static void removeTrackedSign(Location signLocation, boolean refund, boolean forceRefund) throws IOException {
if (!trackedSigns.containsKey(signLocation)) {
return;
}
TrackedSign trackedSign = trackedSigns.get(signLocation);
trackedSigns.remove(signLocation);
saveTrackedSigns();
refund(trackedSign, refund);
refund(trackedSign, refund, forceRefund);
}
/**
@ -113,7 +114,7 @@ public final class TrackedSignManager {
Bukkit.getScheduler().scheduleSyncDelayedTask(PaidSigns.getInstance(), () -> {
PaidSigns.getInstance().getLogger().log(Level.WARNING, "The sign at " + signLocation +
" no longer exists. Removing from sign tracker. Refunding the player.");
refund(trackedSign, true);
refund(trackedSign, true, false);
}, 100);
return;
}
@ -145,9 +146,10 @@ public final class TrackedSignManager {
*
* @param trackedSign <p>The tracked sign to refund for</p>
* @param refund <p>Whether to actually refund</p>
* @param forceRefund <p>Whether to force a refund, even if refunding is disabled</p>
*/
private static void refund(TrackedSign trackedSign, boolean refund) {
if (!PaidSigns.getInstance().areRefundsEnabled() || !refund) {
private static void refund(TrackedSign trackedSign, boolean refund, boolean forceRefund) {
if ((!PaidSigns.getInstance().areRefundsEnabled() || !refund) && !forceRefund) {
return;
}
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(trackedSign.playerId());