4 Commits

8 changed files with 150 additions and 46 deletions

View File

@ -88,6 +88,8 @@ Removes a registered paid sign
* ignoreColor - Whether to ignore any color or formatting applied to the text when trying to match a paid sign's text.
The option can be set on a per-sign basis, but this value is used if not specified. The correct value depends on
whether the plugin signs it should match allow coloring or not.
* enableRefunds - Whether to enable refunds to the sign creator when a sign detected as a paid sign is broken (payment
* refundsEnabled - Whether to enable refunds to the sign creator when a sign detected as a paid sign is broken (payment
will always go to the original creator)
* refundPercentage - The percentage of the paid sign cost to refund (0-100)
* refundPercentage - The percentage of the paid sign cost to refund (0-100)
* refundAlways - Whether to refund when signs that players have paid for are broken by anything. This includes tnt,
creepers, pistons and similar

View File

@ -6,7 +6,7 @@
<groupId>net.knarcraft</groupId>
<artifactId>paidsigns</artifactId>
<version>0.4.0-ALPHA</version>
<version>0.5.0-ALPHA</version>
<packaging>jar</packaging>
<name>Paid Signs</name>
@ -25,8 +25,8 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>16</source>
<target>16</target>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
<plugin>

View File

@ -11,7 +11,7 @@ import net.knarcraft.paidsigns.command.RemoveConditionCommand;
import net.knarcraft.paidsigns.command.RemoveConditionTabCompleter;
import net.knarcraft.paidsigns.command.RemoveTabCommand;
import net.knarcraft.paidsigns.formatting.Translator;
import net.knarcraft.paidsigns.listener.BlockBreakListener;
import net.knarcraft.paidsigns.listener.SignBreakListener;
import net.knarcraft.paidsigns.listener.SignListener;
import net.knarcraft.paidsigns.manager.EconomyManager;
import net.knarcraft.paidsigns.manager.PaidSignManager;
@ -37,8 +37,9 @@ public final class PaidSigns extends JavaPlugin {
private String language;
private boolean ignoreCase;
private boolean ignoreColor;
private boolean enableRefunds;
private int refundPercentage;
private boolean refundsEnabled;
private short refundPercentage;
private boolean refundAlways;
/**
* Instantiates a new paid signs object
@ -67,7 +68,7 @@ public final class PaidSigns extends JavaPlugin {
PluginManager pluginManager = getServer().getPluginManager();
pluginManager.registerEvents(new SignListener(), this);
pluginManager.registerEvents(new BlockBreakListener(), this);
pluginManager.registerEvents(new SignBreakListener(), this);
registerCommands();
}
@ -120,7 +121,7 @@ public final class PaidSigns extends JavaPlugin {
* @return <p>Whether refunds are currently enabled</p>
*/
public boolean areRefundsEnabled() {
return this.enableRefunds;
return this.refundsEnabled;
}
/**
@ -128,7 +129,7 @@ public final class PaidSigns extends JavaPlugin {
*
* @return <p>The percentage of the cost to refund</p>
*/
public int getRefundPercentage() {
public short getRefundPercentage() {
if (this.refundPercentage < 0) {
return 0;
} else if (refundPercentage > 100) {
@ -137,6 +138,15 @@ public final class PaidSigns extends JavaPlugin {
return this.refundPercentage;
}
/**
* Gets whether refunds should always happen, even if signs are not broken by players
*
* @return <p>True if refunds should always happen</p>
*/
public boolean refundAlways() {
return this.refundAlways;
}
/**
* Registers the commands used by this plugin
*/
@ -175,11 +185,12 @@ public final class PaidSigns extends JavaPlugin {
config.options().copyDefaults(true);
this.saveDefaultConfig();
this.saveConfig();
language = config.getString("language", "en");
ignoreCase = config.getBoolean("ignoreCase", true);
ignoreColor = config.getBoolean("ignoreColor", false);
enableRefunds = config.getBoolean("enableRefunds", true);
refundPercentage = config.getInt("refundPercentage", 100);
language = config.getString("language", "en");
refundsEnabled = config.getBoolean("refundsEnabled", true);
refundPercentage = (short) config.getInt("refundPercentage", 100);
refundAlways = config.getBoolean("refundAlways", false);
}
/**

View File

@ -1,27 +0,0 @@
package net.knarcraft.paidsigns.listener;
import net.knarcraft.paidsigns.manager.TrackedSignManager;
import org.bukkit.block.Sign;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import java.io.IOException;
/**
* A listener that listens for any tracked signs being broken
*/
public class BlockBreakListener implements Listener {
@EventHandler(priority = EventPriority.MONITOR)
public void onBlockBreak(BlockBreakEvent event) {
if (event.getBlock().getState() instanceof Sign) {
try {
TrackedSignManager.removeTrackedSign(event.getBlock().getLocation());
} catch (IOException ignored) {
}
}
}
}

View File

@ -0,0 +1,103 @@
package net.knarcraft.paidsigns.listener;
import net.knarcraft.paidsigns.PaidSigns;
import net.knarcraft.paidsigns.manager.TrackedSignManager;
import org.bukkit.block.Block;
import org.bukkit.block.Sign;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockExplodeEvent;
import org.bukkit.event.block.BlockPistonExtendEvent;
import org.bukkit.event.block.BlockPistonRetractEvent;
import org.bukkit.event.entity.EntityChangeBlockEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import java.io.IOException;
import java.util.List;
/**
* A listener that listens for any tracked signs being broken
*/
public class SignBreakListener implements Listener {
@EventHandler(priority = EventPriority.MONITOR)
public void onBlockBreak(BlockBreakEvent event) {
if (event.isCancelled()) {
return;
}
removeTrackedSign(event.getBlock(), true);
}
@EventHandler(priority = EventPriority.MONITOR)
public void onExplosion(BlockExplodeEvent event) {
if (event.isCancelled()) {
return;
}
removeTrackedSigns(event.blockList());
}
@EventHandler(priority = EventPriority.MONITOR)
public void onEntityExplosion(EntityExplodeEvent event) {
if (event.isCancelled()) {
return;
}
removeTrackedSigns(event.blockList());
}
@EventHandler(priority = EventPriority.MONITOR)
public void onPistonPush(BlockPistonExtendEvent event) {
if (event.isCancelled()) {
return;
}
removeTrackedSigns(event.getBlocks());
}
@EventHandler(priority = EventPriority.MONITOR)
public void onPistonPull(BlockPistonRetractEvent event) {
if (event.isCancelled()) {
return;
}
removeTrackedSigns(event.getBlocks());
}
@EventHandler(priority = EventPriority.MONITOR)
public void onEntityBlockChange(EntityChangeBlockEvent event) {
if (event.isCancelled()) {
return;
}
if (event.getEntity() instanceof Player) {
return;
}
removeTrackedSign(event.getBlock(), PaidSigns.getInstance().refundAlways());
}
/**
* Removes all tracked signs from the given blocks
*
* @param blocks <p>The blocks to search for tracked signs</p>
*/
private void removeTrackedSigns(List<Block> blocks) {
for (Block block : blocks) {
removeTrackedSign(block, PaidSigns.getInstance().refundAlways());
}
}
/**
* Tries to remove any tracked sign at the given block
*
* @param block <p>The block that might be a sign</p>
* @param refund <p>Whether to perform a refund after un-tracking the sign</p>
*/
private void removeTrackedSign(Block block, boolean refund) {
if (block.getState() instanceof Sign) {
try {
TrackedSignManager.removeTrackedSign(block.getLocation(), refund);
} catch (IOException ignored) {
}
}
}
}

View File

@ -58,4 +58,14 @@ public final class EconomyManager {
economy.withdrawPlayer(player, cost);
}
/**
* Deposits a given sum into the given player's account
*
* @param player <p>The player to deposit money to</p>
* @param sum <p>The amount of money to deposit</p>
*/
public static void deposit(OfflinePlayer player, double sum) {
economy.depositPlayer(player, sum);
}
}

View File

@ -49,21 +49,22 @@ public final class TrackedSignManager {
* Removes a tracked sign from the manager
*
* @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>
* @throws IOException <p>If unable to save the tracked signs</p>
*/
public static void removeTrackedSign(Location signLocation) throws IOException {
public static void removeTrackedSign(Location signLocation, boolean refund) throws IOException {
if (!trackedSigns.containsKey(signLocation)) {
return;
}
TrackedSign trackedSign = trackedSigns.get(signLocation);
trackedSigns.remove(signLocation);
saveTrackedSigns();
if (!PaidSigns.getInstance().areRefundsEnabled()) {
if (!PaidSigns.getInstance().areRefundsEnabled() || !refund) {
return;
}
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(trackedSign.getPlayerId());
double refundSum = trackedSign.getCost() / 100 * PaidSigns.getInstance().getRefundPercentage();
EconomyManager.withdraw(offlinePlayer, -refundSum);
EconomyManager.deposit(offlinePlayer, refundSum);
if (offlinePlayer instanceof Player player) {
player.sendMessage(String.format(StringFormatter.replacePlaceholders(
StringFormatter.getTranslatedInfoMessage(TranslatableMessage.SUCCESS_REFUNDED),

View File

@ -13,7 +13,11 @@ ignoreColor: false
# Whether to enable refunds to the sign creator when a sign detected as a paid sign is broken (payment will always go
# to the original creator)
enableRefunds: true
refundsEnabled: true
# The percentage of the paid sign cost to refund (0-100)
refundPercentage: 100
refundPercentage: 100
# Whether to refund when signs that players have paid for are broken by anything. This includes tnt, creepers, pistons
# and similar
refundAlways: false