4 Commits

Author SHA1 Message Date
814a6dc701 Adds POM relocations
All checks were successful
KnarCraft/PaidSigns/pipeline/head This commit looks good
2024-05-03 15:40:12 +02:00
4f3c27e4bd Bumps dev version
All checks were successful
KnarCraft/PaidSigns/pipeline/head This commit looks good
2023-06-25 16:42:14 +02:00
2bc4ab22f5 Bumps version for release
Some checks failed
EpicKnarvik97/PaidSigns/pipeline/head This commit looks good
KnarCraft/PaidSigns/pipeline/head There was a failure building this commit
2023-06-25 16:41:16 +02:00
396bcfc68b Adds proper support for dual-side paid signs 2023-06-24 15:07:03 +02:00
5 changed files with 157 additions and 20 deletions

22
pom.xml
View File

@ -6,7 +6,7 @@
<groupId>net.knarcraft</groupId>
<artifactId>paidsigns</artifactId>
<version>1.0.2</version>
<version>1.0.4-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Paid Signs</name>
@ -32,7 +32,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<version>3.3.0</version>
<executions>
<execution>
<phase>package</phase>
@ -41,6 +41,16 @@
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<relocations>
<relocation>
<pattern>net.knarcraft.knarlib</pattern>
<shadedPattern>net.knarcraft.paidsigns.lib.knarlib</shadedPattern>
</relocation>
<relocation>
<pattern>org.jetbrains.annotations</pattern>
<shadedPattern>net.knarcraft.paidsigns.lib.annotations</shadedPattern>
</relocation>
</relocations>
<filters>
<filter>
<artifact>net.knarcraft:knarlib</artifact>
@ -48,6 +58,12 @@
<include>net/knarcraft/knarlib/**</include>
</includes>
</filter>
<filter>
<artifact>org.jetbrains:annotations</artifact>
<includes>
<include>org/jetbrains/annotations/**</include>
</includes>
</filter>
<filter>
<excludes>
<exclude>*.MF</exclude>
@ -107,7 +123,7 @@
<dependency>
<groupId>com.github.MilkBowl</groupId>
<artifactId>VaultAPI</artifactId>
<version>1.7</version>
<version>1.7.1</version>
<scope>provided</scope>
</dependency>
<dependency>

View File

@ -1,13 +1,45 @@
package net.knarcraft.paidsigns.container;
import org.bukkit.block.sign.Side;
import java.util.UUID;
/**
* A representation of a sign placed by a player that matched a paid sign
*
* @param playerId <p>The unique id of the player that created the sign</p>
* @param cost <p>The cost the player paid for creating the sign</p>
* @param playerId <p>The unique id of the player that created the sign</p>
* @param frontCost <p>The cost the player paid for creating the front of the sign</p>
* @param backCost <p>The cost the player paid for creating the back of the sign</p>
*/
public record TrackedSign(UUID playerId, double cost) {
public record TrackedSign(UUID playerId, double frontCost, double backCost) {
/**
* Gets an instance of a tracked sign
*
* @param playerId <p>The unique id of the player that created the sign</p>
* @param side <p>The side the player paid for</p>
* @param cost <p>The cost the player paid for creating the side of the sign</p>
* @return <p>A tracked sign instance</p>
*/
public static TrackedSign getInstance(UUID playerId, Side side, double cost) {
if (side == Side.FRONT) {
return new TrackedSign(playerId, cost, 0);
} else {
return new TrackedSign(playerId, 0, cost);
}
}
/**
* Gets the cost paid for the given side
*
* @param side <p>The side to check the cost for</p>
* @return <p>The cost the player paid</p>
*/
public double getCost(Side side) {
return switch (side) {
case FRONT -> frontCost;
case BACK -> backCost;
};
}
}

View File

@ -30,7 +30,6 @@ import java.util.logging.Level;
public class SignListener implements Listener {
@EventHandler(priority = EventPriority.LOW)
@SuppressWarnings("unused")
public void onSignChange(SignChangeEvent event) {
if (event.isCancelled() || event.getPlayer().hasPermission("paidsigns.paymentexempt")) {
return;
@ -39,7 +38,8 @@ public class SignListener implements Listener {
// As signs can be edited now, this event might be triggered on an already registered sign, so unregister
if (SignHelper.isSign(event.getBlock())) {
try {
TrackedSignManager.removeTrackedSign(event.getBlock().getLocation(), true, false);
TrackedSignManager.removeTrackedSign(event.getBlock().getLocation(), true, false,
event.getSide());
} catch (IOException ignored) {
}
}
@ -164,7 +164,7 @@ public class SignListener implements Listener {
EconomyManager.withdraw(player, cost);
PaidSigns.getStringFormatter().displaySuccessMessage(player, replaceCost(cost, PaidSignsTranslatableMessage.SUCCESS_PAID_FOR_SIGN));
try {
TrackedSignManager.addTrackedSign(event.getBlock().getLocation(), player.getUniqueId(), cost);
TrackedSignManager.addTrackedSign(event.getBlock().getLocation(), player.getUniqueId(), cost, event.getSide());
} catch (IOException ignored) {
}
}

View File

@ -7,6 +7,7 @@ import net.knarcraft.paidsigns.utility.SignHelper;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.block.sign.Side;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
@ -36,13 +37,72 @@ public final class TrackedSignManager {
*
* @param signLocation <p>The location the sign was created at</p>
* @param playerId <p>The unique id of the player that created the sign</p>
* @param cost <p>The cost the player paid</p>
* @param side <p>The side of the sign the player paid for</p>
* @throws IOException <p>If unable to save the tracked signs</p>
*/
public static void addTrackedSign(Location signLocation, UUID playerId, double cost) throws IOException {
trackedSigns.put(signLocation, new TrackedSign(playerId, cost));
public static void addTrackedSign(Location signLocation, UUID playerId, double cost, Side side) throws IOException {
if (trackedSigns.containsKey(signLocation)) {
// If there is already a tracked sign, overwrite it, while updating only the correct cost
TrackedSign oldSign = trackedSigns.get(signLocation);
if (side == Side.FRONT) {
trackedSigns.put(signLocation, new TrackedSign(playerId, cost, oldSign.backCost()));
} else {
trackedSigns.put(signLocation, new TrackedSign(playerId, oldSign.frontCost(), cost));
}
} else {
trackedSigns.put(signLocation, TrackedSign.getInstance(playerId, side, cost));
}
saveTrackedSigns();
}
/**
* 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>
* @param forceRefund <p>Whether to force a refund, even if refunding is disabled</p>
* @param side <p>The side of the sign to un-track</p>
* @throws IOException <p>If unable to save the tracked signs</p>
*/
public static void removeTrackedSign(Location signLocation, boolean refund, boolean forceRefund,
Side side) throws IOException {
if (!trackedSigns.containsKey(signLocation)) {
return;
}
TrackedSign trackedSign = trackedSigns.get(signLocation);
Side oppositeSide = getOppositeSide(side);
double oppositeCost = trackedSign.getCost(oppositeSide);
boolean isInUse = oppositeCost > 0;
if (!isInUse) {
trackedSigns.remove(signLocation);
} else {
// If the opposite side has a cost, create a new sign with only that cost
trackedSigns.put(signLocation, TrackedSign.getInstance(trackedSign.playerId(), oppositeSide, oppositeCost));
}
saveTrackedSigns();
if (trackedSign.getCost(side) > 0) {
refund(trackedSign, refund, forceRefund, side);
}
}
/**
* Gets the opposite sign side of the given side
*
* @param side <p>The side to get the opposite of</p>
* @return <p>The opposite sign side</p>
*/
private static Side getOppositeSide(Side side) {
if (side == Side.FRONT) {
return Side.BACK;
} else {
return Side.FRONT;
}
}
/**
* Removes a tracked sign from the manager
*
@ -58,7 +118,7 @@ public final class TrackedSignManager {
TrackedSign trackedSign = trackedSigns.get(signLocation);
trackedSigns.remove(signLocation);
saveTrackedSigns();
refund(trackedSign, refund, forceRefund);
refundBothSides(trackedSign, refund, forceRefund);
}
/**
@ -105,16 +165,27 @@ public final class TrackedSignManager {
return;
}
double cost = signSection.getDouble(key + ".cost");
double frontCost;
double backCost = 0;
if (signSection.contains(key + ".cost")) {
// Migrate from single side cost to two side cost
frontCost = signSection.getDouble(key + ".cost");
signSection.set(key + ".cost", null);
} else {
frontCost = signSection.getDouble(key + ".frontCost");
}
if (signSection.contains(key + ".backCost")) {
backCost = signSection.getDouble(key + ".backCost");
}
UUID playerId = UUID.fromString(Objects.requireNonNull(signSection.getString(key + ".playerId")));
TrackedSign trackedSign = new TrackedSign(playerId, cost);
TrackedSign trackedSign = new TrackedSign(playerId, frontCost, backCost);
//Prevent destroyed signs from being tracked indefinitely
if (!SignHelper.isSign(signLocation.getBlock())) {
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, false);
refundBothSides(trackedSign, true, false);
}, 100);
return;
}
@ -135,7 +206,8 @@ public final class TrackedSignManager {
TrackedSign sign = trackedSigns.get(signLocation);
String locationString = Objects.requireNonNull(signLocation.getWorld()).getUID() + "," +
signLocation.getBlockX() + "," + signLocation.getBlockY() + "," + signLocation.getBlockZ();
signSection.set(locationString + ".cost", sign.cost());
signSection.set(locationString + ".frontCost", sign.frontCost());
signSection.set(locationString + ".backCost", sign.backCost());
signSection.set(locationString + ".playerId", sign.playerId().toString());
}
configuration.save(signsFile);
@ -148,17 +220,18 @@ public final class TrackedSignManager {
* @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, boolean forceRefund) {
private static void refund(TrackedSign trackedSign, boolean refund, boolean forceRefund, Side signSide) {
if ((!PaidSigns.getInstance().areRefundsEnabled() || !refund) && !forceRefund) {
return;
}
double cost = trackedSign.getCost(signSide);
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(trackedSign.playerId());
double refundSum;
if (forceRefund) {
//In the case where a refund is forced, the normal refund rate should not apply
refundSum = trackedSign.cost();
refundSum = cost;
} else {
refundSum = trackedSign.cost() / 100 * PaidSigns.getInstance().getRefundPercentage();
refundSum = cost / 100 * PaidSigns.getInstance().getRefundPercentage();
}
EconomyManager.deposit(offlinePlayer, refundSum);
if (offlinePlayer instanceof Player player) {
@ -168,4 +241,20 @@ public final class TrackedSignManager {
}
}
/**
* Refunds the costs for both sides of a paid sign
*
* @param trackedSign <p>The tracked sign to refund for</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>
*/
private static void refundBothSides(TrackedSign trackedSign, boolean refund, boolean forceRefund) {
if (trackedSign.frontCost() > 0) {
refund(trackedSign, refund, forceRefund, Side.FRONT);
}
if (trackedSign.backCost() > 0) {
refund(trackedSign, refund, forceRefund, Side.BACK);
}
}
}

View File

@ -1,7 +1,7 @@
name: PaidSigns
version: '${project.version}'
main: net.knarcraft.paidsigns.PaidSigns
api-version: '1.19'
api-version: '1.20'
prefix: PaidSigns
depend: [ Vault ]
authors: [ EpicKnarvik97 ]