From 7756813d015a88c571ccf43dbe5f4d5eeb93dea2 Mon Sep 17 00:00:00 2001 From: Allink Date: Sat, 20 May 2023 04:00:51 +0100 Subject: [PATCH 01/22] Add mutable audience forwarder class This class allows for ForwardingAudience-esque behaviour, while being mutable. It is currently not thread safe. It was implemented as we need a good way to implement a "TransactionSpy" (or "EconomySpy", maybe) in the future, once we finalize planned administrative functions. --- .../audience/MutableAudienceForwarder.java | 244 ++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100644 Patchwork/src/main/java/me/totalfreedom/audience/MutableAudienceForwarder.java diff --git a/Patchwork/src/main/java/me/totalfreedom/audience/MutableAudienceForwarder.java b/Patchwork/src/main/java/me/totalfreedom/audience/MutableAudienceForwarder.java new file mode 100644 index 0000000..60fc88b --- /dev/null +++ b/Patchwork/src/main/java/me/totalfreedom/audience/MutableAudienceForwarder.java @@ -0,0 +1,244 @@ +package me.totalfreedom.audience; + +import net.kyori.adventure.audience.Audience; +import net.kyori.adventure.bossbar.BossBar; +import net.kyori.adventure.chat.ChatType; +import net.kyori.adventure.chat.SignedMessage; +import net.kyori.adventure.inventory.Book; +import net.kyori.adventure.sound.Sound; +import net.kyori.adventure.sound.SoundStop; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.ComponentLike; +import net.kyori.adventure.title.Title; +import net.kyori.adventure.title.TitlePart; +import org.jetbrains.annotations.NotNull; + +import java.util.HashSet; +import java.util.Set; +import java.util.function.Consumer; +import java.util.function.Predicate; + +/** + * A replacement for {@link net.kyori.adventure.audience.ForwardingAudience} that allows for audiences to be removed & added at will. Not thread safe. + *

+ * This is intended for use in toggleable logging systems, for example, potion spy. + */ +// TODO: Work on thread-safety (or thread-safe alternative) +public class MutableAudienceForwarder implements Audience +{ + private final Set audiences = new HashSet<>(); + + public static MutableAudienceForwarder from(Audience... audiences) + { + MutableAudienceForwarder audienceForwarder = new MutableAudienceForwarder(); + + for (Audience audience : audiences) + { + audienceForwarder.addAudience(audience); + } + + return audienceForwarder; + } + + public void addAudience(Audience audience) + { + if (audiences.contains(audience) || audience == this /* Protect against honest self-referential calls */) + { + return; + } + + audiences.add(audience); + } + + public boolean removeAudience(Audience audience) + { + return audiences.remove(audience); + } + + + @Override + public @NotNull Audience filterAudience(@NotNull Predicate filter) + { + return audiences.stream() + .filter(filter) + .findFirst() + .orElseThrow(); + } + + @Override + public void forEachAudience(@NotNull Consumer action) + { + audiences.forEach(action); + } + + @Override + public void sendMessage(@NotNull ComponentLike message) + { + audiences.forEach(a -> a.sendMessage(message)); + } + + @Override + public void sendMessage(@NotNull Component message) + { + audiences.forEach(a -> a.sendMessage(message)); + } + + @Override + public void sendMessage(@NotNull Component message, ChatType.@NotNull Bound boundChatType) + { + audiences.forEach(a -> a.sendMessage(message, boundChatType)); + } + + @Override + public void sendMessage(@NotNull ComponentLike message, ChatType.@NotNull Bound boundChatType) + { + audiences.forEach(a -> a.sendMessage(message, boundChatType)); + } + + @Override + public void sendMessage(@NotNull SignedMessage signedMessage, ChatType.@NotNull Bound boundChatType) + { + audiences.forEach(a -> a.sendMessage(signedMessage, boundChatType)); + } + + @Override + public void deleteMessage(@NotNull SignedMessage signedMessage) + { + audiences.forEach(a -> a.deleteMessage(signedMessage)); + } + + @Override + public void deleteMessage(SignedMessage.@NotNull Signature signature) + { + audiences.forEach(a -> a.deleteMessage(signature)); + } + + // The methods below here will (probably) never be used, however it's good to keep them for completeness' sake. + + @Override + public void sendActionBar(@NotNull ComponentLike message) + { + audiences.forEach(a -> a.sendActionBar(message)); + } + + @Override + public void sendActionBar(@NotNull Component message) + { + audiences.forEach(a -> a.sendActionBar(message)); + } + + @Override + public void sendPlayerListHeader(@NotNull ComponentLike header) + { + audiences.forEach(a -> a.sendPlayerListHeader(header)); + } + + @Override + public void sendPlayerListHeader(@NotNull Component header) + { + audiences.forEach(a -> a.sendPlayerListHeader(header)); + } + + @Override + public void sendPlayerListFooter(@NotNull ComponentLike footer) + { + audiences.forEach(a -> a.sendPlayerListFooter(footer)); + } + + @Override + public void sendPlayerListFooter(@NotNull Component footer) + { + audiences.forEach(a -> a.sendPlayerListFooter(footer)); + } + + @Override + public void sendPlayerListHeaderAndFooter(@NotNull ComponentLike header, @NotNull ComponentLike footer) + { + audiences.forEach(a -> a.sendPlayerListHeaderAndFooter(header, footer)); + } + + @Override + public void sendPlayerListHeaderAndFooter(@NotNull Component header, @NotNull Component footer) + { + audiences.forEach(a -> a.sendPlayerListHeaderAndFooter(header, footer)); + } + + @Override + public void showTitle(@NotNull Title title) + { + audiences.forEach(a -> a.showTitle(title)); + } + + @Override + public void sendTitlePart(@NotNull TitlePart part, @NotNull T value) + { + audiences.forEach(a -> a.sendTitlePart(part, value)); + } + + @Override + public void clearTitle() + { + audiences.forEach(Audience::clearTitle); + } + + @Override + public void resetTitle() + { + audiences.forEach(Audience::resetTitle); + } + + @Override + public void showBossBar(@NotNull BossBar bar) + { + audiences.forEach(a -> a.showBossBar(bar)); + } + + @Override + public void hideBossBar(@NotNull BossBar bar) + { + audiences.forEach(a -> a.hideBossBar(bar)); + } + + @Override + public void playSound(@NotNull Sound sound) + { + audiences.forEach(a -> a.playSound(sound)); + } + + @Override + public void playSound(@NotNull Sound sound, double x, double y, double z) + { + + audiences.forEach(a -> a.playSound(sound, x, y, z)); + } + + @Override + public void playSound(@NotNull Sound sound, Sound.@NotNull Emitter emitter) + { + audiences.forEach(a -> a.playSound(sound, emitter)); + } + + @Override + public void stopSound(@NotNull Sound sound) + { + audiences.forEach(a -> a.stopSound(sound)); + } + + @Override + public void stopSound(@NotNull SoundStop stop) + { + audiences.forEach(a -> a.stopSound(stop)); + } + + @Override + public void openBook(Book.@NotNull Builder book) + { + audiences.forEach(a -> a.openBook(book)); + } + + @Override + public void openBook(@NotNull Book book) + { + audiences.forEach(a -> a.openBook(book)); + } +} From 55859b6b15074f0d822870f72b98c23bda60c077 Mon Sep 17 00:00:00 2001 From: Allink Date: Sat, 20 May 2023 04:07:55 +0100 Subject: [PATCH 02/22] Add adventure utility class This class is meant to track a global PlainTextComponentSerializer instance, so we don't have to call PlainTextComponentSerializer#plainText in every class that needs to serialize a Component into a String. I implemented this so I can add component logging to FreedomLogger. --- .../totalfreedom/utils/FreedomAdventure.java | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 Patchwork/src/main/java/me/totalfreedom/utils/FreedomAdventure.java diff --git a/Patchwork/src/main/java/me/totalfreedom/utils/FreedomAdventure.java b/Patchwork/src/main/java/me/totalfreedom/utils/FreedomAdventure.java new file mode 100644 index 0000000..cd0fa3d --- /dev/null +++ b/Patchwork/src/main/java/me/totalfreedom/utils/FreedomAdventure.java @@ -0,0 +1,48 @@ +package me.totalfreedom.utils; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; + +import java.util.function.Supplier; + +/** + * This class contains the only reference to plain text component serializer, and allows access to it via wrapper functions. + */ +public class FreedomAdventure +{ + private FreedomAdventure() + { + throw new UnsupportedOperationException("Instantiation of a static utility class is not supported."); + } + + private static final PlainTextComponentSerializer PLAIN_TEXT_COMPONENT_SERIALIZER = PlainTextComponentSerializer.plainText(); + + public static String toPlainText(Component component) + { + return PLAIN_TEXT_COMPONENT_SERIALIZER.serialize(component); + } + + public static String toPlainText(Supplier supplier) + { + return toPlainText(supplier.get()); + } + + public static Supplier supplyPlainText(Supplier supplier) + { + return new StringRepresentationSupplier(supplier.get()); + } + + public static Supplier supplyPlainText(Component component) + { + return new StringRepresentationSupplier(component); + } + + private record StringRepresentationSupplier(Component component) implements Supplier + { + @Override + public String get() + { + return PLAIN_TEXT_COMPONENT_SERIALIZER.serialize(component); + } + } +} From 12cfdfe31d4e58e56b2da399747d14bfa0a6301e Mon Sep 17 00:00:00 2001 From: Allink Date: Sat, 20 May 2023 04:26:11 +0100 Subject: [PATCH 03/22] Add methods specifically for logging components to FreedomLogger The new component-logging methods are ALL suffixed with "Component" to prevent type erasure conflicts with the other Supplier methods. These methods were added for completeness for when I make the FreedomLogger an Audience. --- .../me/totalfreedom/utils/FreedomLogger.java | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/Patchwork/src/main/java/me/totalfreedom/utils/FreedomLogger.java b/Patchwork/src/main/java/me/totalfreedom/utils/FreedomLogger.java index c0deaa1..219a2e5 100644 --- a/Patchwork/src/main/java/me/totalfreedom/utils/FreedomLogger.java +++ b/Patchwork/src/main/java/me/totalfreedom/utils/FreedomLogger.java @@ -36,6 +36,20 @@ public class FreedomLogger logger.info(message); } + /** + * This method allows you to log a component to the console. + * + * @param component The component to send. + * @return A plain text representation of the message + */ + public String infoComponent(Component component) + { + String plainText = FreedomAdventure.toPlainText(component); + + logger.info(plainText); + return plainText; + } + /** * This method allows you to log a message to the console, * while also returning a Component that could be used to @@ -50,6 +64,19 @@ public class FreedomLogger return Component.text(message.get()); } + /** + * This method allows you to log a component to the console, + * while also returning a String representation of the + * component + * + * @param component The component to send. + * @return A string representation of the message. + */ + public String infoComponent(Supplier component) + { + return this.infoComponent(component.get()); + } + /** * This method allows you to log a warning to the console. * @@ -60,6 +87,18 @@ public class FreedomLogger logger.warn(message); } + /** + * This method allows you to log a warning to the console. + * + * @param component The component to send. + */ + public void warnComponent(Component component) + { + String plainText = FreedomAdventure.toPlainText(component); + + logger.warn(plainText); + } + /** * This method logs an error message to the console. * It is highly recommended to deconstruct the stack trace and pass it @@ -72,6 +111,20 @@ public class FreedomLogger logger.error(message); } + /** + * This method logs an error component to the console. + * + * @param component The message to send. + */ + public String errorComponent(Component component) + { + String plainText = FreedomAdventure.toPlainText(component); + + logger.error(plainText); + + return plainText; + } + /** * This method allows you to log an exception directly to the console. * @@ -98,6 +151,19 @@ public class FreedomLogger return Component.text(message.get()); } + /** + * This method allows you to log an error component to the console, + * while also returning a String representation of the error + * component. + * + * @param component The component to send. + * @return A String representation of the component. + */ + public String errorComponent(Supplier component) + { + return this.errorComponent(component.get()); + } + /** * This method allows you to log a debug message to the console. * This method will only log if debug mode is enabled. @@ -110,6 +176,21 @@ public class FreedomLogger logger.debug(message); } + /** + * This method allows you to log a debug component to the console. + * This method will only log if debug mode is enabled. + * + * @param component The component to send. + */ + public String debugComponent(Component component) + { + String plainText = FreedomAdventure.toPlainText(component); + + this.debug(plainText); + + return plainText; + } + /** * This method allows you to log a debug message to the console, * while also returning a Component that could be used to @@ -128,4 +209,21 @@ public class FreedomLogger } return Component.empty(); } + + /** + * This method allows you to log a debug component to the console, + * while also returning a String representation of the debug component. + * + * @param component The component to send. + * @return A String representation of the message. + */ + public String debugComponent(Supplier component) + { + if (debug) + { + return this.debugComponent(component.get()); + } + return ""; + } + } From 2fd2008f6510408fb94aebdb32b69c56efa73298 Mon Sep 17 00:00:00 2001 From: Allink Date: Sat, 20 May 2023 04:31:18 +0100 Subject: [PATCH 04/22] Make the FreedomLogger an Audience This will allow for a FreedomLogger instance to be added to any collection of audiences. This was written for usage in a future TransactionSpy implementation. --- .../me/totalfreedom/utils/FreedomLogger.java | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/Patchwork/src/main/java/me/totalfreedom/utils/FreedomLogger.java b/Patchwork/src/main/java/me/totalfreedom/utils/FreedomLogger.java index 219a2e5..6172443 100644 --- a/Patchwork/src/main/java/me/totalfreedom/utils/FreedomLogger.java +++ b/Patchwork/src/main/java/me/totalfreedom/utils/FreedomLogger.java @@ -1,12 +1,17 @@ package me.totalfreedom.utils; +import net.kyori.adventure.audience.Audience; +import net.kyori.adventure.chat.ChatType; +import net.kyori.adventure.chat.SignedMessage; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.ComponentLike; +import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.function.Supplier; -public class FreedomLogger +public class FreedomLogger implements Audience { private final Logger logger; private boolean debug = false; @@ -226,4 +231,42 @@ public class FreedomLogger return ""; } + + @Override + public void sendMessage(@NotNull ComponentLike message) + { + Component component = ComponentLike.unbox(message); + + if (component == null) + { + this.info("**null component-like**"); + return; + } + + this.infoComponent(component); + } + + @Override + public void sendMessage(@NotNull Component message) + { + this.infoComponent(message); + } + + @Override + public void sendMessage(@NotNull Component message, ChatType.@NotNull Bound boundChatType) + { + this.infoComponent(message); + } + + @Override + public void sendMessage(@NotNull ComponentLike message, ChatType.@NotNull Bound boundChatType) + { + this.sendMessage(message); + } + + @Override + public void sendMessage(@NotNull SignedMessage signedMessage, ChatType.@NotNull Bound boundChatType) + { + this.info(signedMessage.message()); // TODO: We might want to investigate whether this logs the ENTIRE message, including unsigned & signed content, or only the signed part. This method was written in the assumption that it provided all content. + } } From 2f18e4d8efdb17604fb29080286c8dbedcb07ca3 Mon Sep 17 00:00:00 2001 From: Allink Date: Sat, 20 May 2023 04:54:55 +0100 Subject: [PATCH 05/22] Add economic entity interfaces I decided to add these interfaces, instead of just building upon the User & UserData interface, as support for commerce between clans & users might be something that we want to add in the future in Clans. --- .../datura/user/SimpleUserData.java | 32 +++++++++++++++++-- .../totalfreedom/economy/EconomicEntity.java | 8 +++++ .../economy/EconomicEntityData.java | 12 +++++++ .../main/java/me/totalfreedom/user/User.java | 17 +++++++++- .../java/me/totalfreedom/user/UserData.java | 3 +- 5 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 Patchwork/src/main/java/me/totalfreedom/economy/EconomicEntity.java create mode 100644 Patchwork/src/main/java/me/totalfreedom/economy/EconomicEntityData.java diff --git a/Datura/src/main/java/me/totalfreedom/datura/user/SimpleUserData.java b/Datura/src/main/java/me/totalfreedom/datura/user/SimpleUserData.java index cb6db2a..8b4fbce 100644 --- a/Datura/src/main/java/me/totalfreedom/datura/user/SimpleUserData.java +++ b/Datura/src/main/java/me/totalfreedom/datura/user/SimpleUserData.java @@ -26,6 +26,7 @@ public class SimpleUserData implements UserData private boolean frozen; private boolean canInteract; private boolean caged; + private long balance; public SimpleUserData(final Player player) { @@ -42,7 +43,8 @@ public class SimpleUserData implements UserData final long playtime, final boolean frozen, final boolean canInteract, - final boolean caged) + final boolean caged, + final long balance) { this.uuid = uuid; this.username = username; @@ -52,6 +54,7 @@ public class SimpleUserData implements UserData this.frozen = frozen; this.canInteract = canInteract; this.caged = caged; + this.balance = balance; } public static SimpleUserData fromSQL(SQL sql, String uuid) @@ -82,7 +85,8 @@ public class SimpleUserData implements UserData boolean frozen = result.getBoolean("frozen"); boolean canInteract = result.getBoolean("canInteract"); boolean caged = result.getBoolean("caged"); - return new SimpleUserData(u, username, user, group, playtime, frozen, canInteract, caged); + long balance = result.getLong("balance"); + return new SimpleUserData(u, username, user, group, playtime, frozen, canInteract, caged, balance); } } catch (SQLException ex) { @@ -197,4 +201,28 @@ public class SimpleUserData implements UserData { this.caged = caged; } + + @Override + public long getBalance() + { + return balance; + } + + @Override + public void addToBalance(long amount) + { + this.balance += amount; + } + + @Override + public void removeFromBalance(long amount) + { + this.balance -= amount; + } + + @Override + public void setBalance(long newBalance) + { + this.balance = newBalance; + } } diff --git a/Patchwork/src/main/java/me/totalfreedom/economy/EconomicEntity.java b/Patchwork/src/main/java/me/totalfreedom/economy/EconomicEntity.java new file mode 100644 index 0000000..1855d1e --- /dev/null +++ b/Patchwork/src/main/java/me/totalfreedom/economy/EconomicEntity.java @@ -0,0 +1,8 @@ +package me.totalfreedom.economy; + +public interface EconomicEntity +{ + EconomicEntityData getEconomicData(); + + String getName(); +} diff --git a/Patchwork/src/main/java/me/totalfreedom/economy/EconomicEntityData.java b/Patchwork/src/main/java/me/totalfreedom/economy/EconomicEntityData.java new file mode 100644 index 0000000..9546489 --- /dev/null +++ b/Patchwork/src/main/java/me/totalfreedom/economy/EconomicEntityData.java @@ -0,0 +1,12 @@ +package me.totalfreedom.economy; + +public interface EconomicEntityData +{ + long getBalance(); + + void addToBalance(final long amount); + + void removeFromBalance(final long amount); + + void setBalance(final long newBalance); +} diff --git a/Patchwork/src/main/java/me/totalfreedom/user/User.java b/Patchwork/src/main/java/me/totalfreedom/user/User.java index 222e2a9..61e8ca3 100644 --- a/Patchwork/src/main/java/me/totalfreedom/user/User.java +++ b/Patchwork/src/main/java/me/totalfreedom/user/User.java @@ -1,10 +1,25 @@ package me.totalfreedom.user; +import me.totalfreedom.economy.EconomicEntity; +import me.totalfreedom.economy.EconomicEntityData; import me.totalfreedom.security.PermissionHolder; import net.kyori.adventure.text.Component; -public interface User extends PermissionHolder +public interface User extends PermissionHolder, EconomicEntity { + // Implement a few EconomicEntity methods in the User interface + @Override + default String getName() + { + return getUserData().getUsername(); + } + + @Override + default EconomicEntityData getEconomicData() + { + return getUserData(); + } + UserData getUserData(); Component getDisplayName(); diff --git a/Patchwork/src/main/java/me/totalfreedom/user/UserData.java b/Patchwork/src/main/java/me/totalfreedom/user/UserData.java index ac2e277..f7ac1d1 100644 --- a/Patchwork/src/main/java/me/totalfreedom/user/UserData.java +++ b/Patchwork/src/main/java/me/totalfreedom/user/UserData.java @@ -1,12 +1,13 @@ package me.totalfreedom.user; +import me.totalfreedom.economy.EconomicEntityData; import me.totalfreedom.security.Group; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.UUID; -public interface UserData +public interface UserData extends EconomicEntityData { @NotNull UUID getUniqueId(); From 8b692d1b11c089a43670f8a1f8637ba06d07a283 Mon Sep 17 00:00:00 2001 From: Allink Date: Sat, 20 May 2023 04:57:19 +0100 Subject: [PATCH 06/22] Add financial transaction classes --- .../economy/SimpleCompletedTransaction.java | 30 ++++++++++ .../fossil/economy/SimpleTransaction.java | 56 +++++++++++++++++++ .../economy/SimpleTransactionResult.java | 42 ++++++++++++++ .../economy/CompletedTransaction.java | 8 +++ .../me/totalfreedom/economy/Transaction.java | 16 ++++++ .../economy/TransactionResult.java | 12 ++++ 6 files changed, 164 insertions(+) create mode 100644 Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleCompletedTransaction.java create mode 100644 Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransaction.java create mode 100644 Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionResult.java create mode 100644 Patchwork/src/main/java/me/totalfreedom/economy/CompletedTransaction.java create mode 100644 Patchwork/src/main/java/me/totalfreedom/economy/Transaction.java create mode 100644 Patchwork/src/main/java/me/totalfreedom/economy/TransactionResult.java diff --git a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleCompletedTransaction.java b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleCompletedTransaction.java new file mode 100644 index 0000000..9080019 --- /dev/null +++ b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleCompletedTransaction.java @@ -0,0 +1,30 @@ +package me.totalfreedom.fossil.economy; + +import me.totalfreedom.economy.CompletedTransaction; +import me.totalfreedom.economy.Transaction; +import me.totalfreedom.economy.TransactionResult; + +public class SimpleCompletedTransaction implements CompletedTransaction +{ + private final Transaction transaction; + private final TransactionResult transactionResult; + + public SimpleCompletedTransaction(Transaction transaction, TransactionResult transactionResult) + { + this.transaction = transaction.copy(); + this.transactionResult = transactionResult; + } + + + @Override + public Transaction getTransaction() + { + return transaction.copy(); + } + + @Override + public TransactionResult getResult() + { + return transactionResult; + } +} diff --git a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransaction.java b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransaction.java new file mode 100644 index 0000000..17e0a13 --- /dev/null +++ b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransaction.java @@ -0,0 +1,56 @@ +package me.totalfreedom.fossil.economy; + +import me.totalfreedom.economy.EconomicEntity; +import me.totalfreedom.economy.Transaction; + +import java.util.concurrent.atomic.AtomicLong; + +public class SimpleTransaction implements Transaction +{ + private final EconomicEntity source; + private final EconomicEntity destination; + private final AtomicLong transferAmount; + + public SimpleTransaction(EconomicEntity source, EconomicEntity destination, long transferAmount) + { + this.source = source; + this.destination = destination; + this.transferAmount = new AtomicLong(transferAmount); + } + + @Override + public Transaction copy() + { + return new SimpleTransaction(source, destination, transferAmount.get()); + } + + @Override + public EconomicEntity getSource() + { + return this.source; + } + + @Override + public EconomicEntity getDestination() + { + return this.destination; + } + + @Override + public long getTransferAmount() + { + return this.transferAmount.get(); + } + + @Override + public long addBalance(long amount) + { + return this.transferAmount.addAndGet(amount); + } + + @Override + public long removeBalance(long amount) + { + return this.addBalance(-amount); + } +} diff --git a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionResult.java b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionResult.java new file mode 100644 index 0000000..57f010a --- /dev/null +++ b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionResult.java @@ -0,0 +1,42 @@ +package me.totalfreedom.fossil.economy; + +import me.totalfreedom.economy.TransactionResult; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; + +public class SimpleTransactionResult implements TransactionResult +{ + private final String message; + private final Component component; + private final boolean successful; + + public SimpleTransactionResult(String message, boolean successful) + { + this(message, Component.text(message, successful ? NamedTextColor.GREEN : NamedTextColor.RED), successful); + } + + public SimpleTransactionResult(String message, Component component, boolean successful) + { + this.message = message; + this.component = component; + this.successful = successful; + } + + @Override + public String getMessage() + { + return message; + } + + @Override + public boolean isSuccessful() + { + return successful; + } + + @Override + public Component getComponent() + { + return component; + } +} diff --git a/Patchwork/src/main/java/me/totalfreedom/economy/CompletedTransaction.java b/Patchwork/src/main/java/me/totalfreedom/economy/CompletedTransaction.java new file mode 100644 index 0000000..5c67cfa --- /dev/null +++ b/Patchwork/src/main/java/me/totalfreedom/economy/CompletedTransaction.java @@ -0,0 +1,8 @@ +package me.totalfreedom.economy; + +public interface CompletedTransaction +{ + Transaction getTransaction(); + + TransactionResult getResult(); +} diff --git a/Patchwork/src/main/java/me/totalfreedom/economy/Transaction.java b/Patchwork/src/main/java/me/totalfreedom/economy/Transaction.java new file mode 100644 index 0000000..d61b3c0 --- /dev/null +++ b/Patchwork/src/main/java/me/totalfreedom/economy/Transaction.java @@ -0,0 +1,16 @@ +package me.totalfreedom.economy; + +public interface Transaction +{ + Transaction copy(); + + EconomicEntity getSource(); + + EconomicEntity getDestination(); + + long getTransferAmount(); + + long addBalance(final long amount); + + long removeBalance(final long amount); +} diff --git a/Patchwork/src/main/java/me/totalfreedom/economy/TransactionResult.java b/Patchwork/src/main/java/me/totalfreedom/economy/TransactionResult.java new file mode 100644 index 0000000..fd4a13d --- /dev/null +++ b/Patchwork/src/main/java/me/totalfreedom/economy/TransactionResult.java @@ -0,0 +1,12 @@ +package me.totalfreedom.economy; + +import net.kyori.adventure.text.Component; + +public interface TransactionResult +{ + String getMessage(); + + boolean isSuccessful(); + + Component getComponent(); +} From 57853a37c5eb859febaf6ab3dbbd46ffdc4f42a2 Mon Sep 17 00:00:00 2001 From: Allink Date: Sat, 20 May 2023 05:14:10 +0100 Subject: [PATCH 07/22] Add transaction freezing --- .../totalfreedom/datura/user/SimpleUserData.java | 14 ++++++++++++-- .../totalfreedom/economy/EconomicEntityData.java | 2 ++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Datura/src/main/java/me/totalfreedom/datura/user/SimpleUserData.java b/Datura/src/main/java/me/totalfreedom/datura/user/SimpleUserData.java index 8b4fbce..e19d3f9 100644 --- a/Datura/src/main/java/me/totalfreedom/datura/user/SimpleUserData.java +++ b/Datura/src/main/java/me/totalfreedom/datura/user/SimpleUserData.java @@ -27,6 +27,7 @@ public class SimpleUserData implements UserData private boolean canInteract; private boolean caged; private long balance; + private boolean transactionsFrozen; public SimpleUserData(final Player player) { @@ -44,7 +45,8 @@ public class SimpleUserData implements UserData final boolean frozen, final boolean canInteract, final boolean caged, - final long balance) + final long balance, + final boolean transactionsFrozen) { this.uuid = uuid; this.username = username; @@ -55,6 +57,7 @@ public class SimpleUserData implements UserData this.canInteract = canInteract; this.caged = caged; this.balance = balance; + this.transactionsFrozen = transactionsFrozen; } public static SimpleUserData fromSQL(SQL sql, String uuid) @@ -86,7 +89,8 @@ public class SimpleUserData implements UserData boolean canInteract = result.getBoolean("canInteract"); boolean caged = result.getBoolean("caged"); long balance = result.getLong("balance"); - return new SimpleUserData(u, username, user, group, playtime, frozen, canInteract, caged, balance); + boolean transactionsFrozen = result.getBoolean("transactionsFrozen"); + return new SimpleUserData(u, username, user, group, playtime, frozen, canInteract, caged, balance, transactionsFrozen); } } catch (SQLException ex) { @@ -202,6 +206,12 @@ public class SimpleUserData implements UserData this.caged = caged; } + @Override + public boolean areTransactionsFrozen() + { + return this.transactionsFrozen; + } + @Override public long getBalance() { diff --git a/Patchwork/src/main/java/me/totalfreedom/economy/EconomicEntityData.java b/Patchwork/src/main/java/me/totalfreedom/economy/EconomicEntityData.java index 9546489..356daac 100644 --- a/Patchwork/src/main/java/me/totalfreedom/economy/EconomicEntityData.java +++ b/Patchwork/src/main/java/me/totalfreedom/economy/EconomicEntityData.java @@ -2,6 +2,8 @@ package me.totalfreedom.economy; public interface EconomicEntityData { + boolean areTransactionsFrozen(); + long getBalance(); void addToBalance(final long amount); From 0e31bea33f31dee08fc8fe5bee6871433891b3cc Mon Sep 17 00:00:00 2001 From: Allink Date: Sat, 20 May 2023 05:20:18 +0100 Subject: [PATCH 08/22] Add transactor & transaction result --- .../economy/SimpleTransactionResult.java | 4 ++ .../fossil/economy/SimpleTransactor.java | 47 +++++++++++++++++++ .../me/totalfreedom/economy/Transactor.java | 6 +++ 3 files changed, 57 insertions(+) create mode 100644 Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactor.java create mode 100644 Patchwork/src/main/java/me/totalfreedom/economy/Transactor.java diff --git a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionResult.java b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionResult.java index 57f010a..55623a3 100644 --- a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionResult.java +++ b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionResult.java @@ -6,6 +6,10 @@ import net.kyori.adventure.text.format.NamedTextColor; public class SimpleTransactionResult implements TransactionResult { + public static final TransactionResult SUCCESSFUL = new SimpleTransactionResult("Successful transaction.", true); + public static final TransactionResult UNAUTHORIZED = new SimpleTransactionResult("Unauthorized transaction.", false); + public static final TransactionResult AMOUNT_TOO_SMALL = new SimpleTransactionResult("Transaction transfer amount too small.", false); + public static final TransactionResult INSUFFICIENT_FUNDS = new SimpleTransactionResult("The source has insufficient funds to carry out this transaction.", false); private final String message; private final Component component; private final boolean successful; diff --git a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactor.java b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactor.java new file mode 100644 index 0000000..b0fedad --- /dev/null +++ b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactor.java @@ -0,0 +1,47 @@ +package me.totalfreedom.fossil.economy; + +import me.totalfreedom.economy.*; + +public class SimpleTransactor implements Transactor +{ + @Override + public CompletedTransaction handleTransaction(Transaction transaction) + { + Transaction transactionCopy = transaction.copy(); + EconomicEntity source = transaction.getSource(); + EconomicEntityData sourceData = source.getEconomicData(); + + if (sourceData.areTransactionsFrozen()) + { + return new SimpleCompletedTransaction(transaction, SimpleTransactionResult.UNAUTHORIZED); + } + + long transactionAmount = transaction.getTransferAmount(); + + if (transactionAmount >= 0) + { + return new SimpleCompletedTransaction(transaction, SimpleTransactionResult.AMOUNT_TOO_SMALL); + } + + long sourceBalance = sourceData.getBalance(); + long diff = sourceBalance - transactionAmount; + + if (diff > 0) + { + return new SimpleCompletedTransaction(transactionCopy, SimpleTransactionResult.INSUFFICIENT_FUNDS); + } + + EconomicEntity destination = transaction.getDestination(); + EconomicEntityData destinationData = destination.getEconomicData(); + + if (destinationData.areTransactionsFrozen()) + { + return new SimpleCompletedTransaction(transaction, SimpleTransactionResult.UNAUTHORIZED); + } + + sourceData.removeFromBalance(transactionAmount); + destinationData.addToBalance(transactionAmount); + + return new SimpleCompletedTransaction(transactionCopy, SimpleTransactionResult.SUCCESSFUL); + } +} diff --git a/Patchwork/src/main/java/me/totalfreedom/economy/Transactor.java b/Patchwork/src/main/java/me/totalfreedom/economy/Transactor.java new file mode 100644 index 0000000..be078ba --- /dev/null +++ b/Patchwork/src/main/java/me/totalfreedom/economy/Transactor.java @@ -0,0 +1,6 @@ +package me.totalfreedom.economy; + +public interface Transactor +{ + CompletedTransaction handleTransaction(Transaction transaction); +} From bdd8c1fb6867e819c680d5ac5f43de66a39dcf94 Mon Sep 17 00:00:00 2001 From: Allink Date: Sat, 20 May 2023 05:21:36 +0100 Subject: [PATCH 09/22] Atomicize balance field in SimpleUserData --- .../me/totalfreedom/datura/user/SimpleUserData.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Datura/src/main/java/me/totalfreedom/datura/user/SimpleUserData.java b/Datura/src/main/java/me/totalfreedom/datura/user/SimpleUserData.java index e19d3f9..fb3e825 100644 --- a/Datura/src/main/java/me/totalfreedom/datura/user/SimpleUserData.java +++ b/Datura/src/main/java/me/totalfreedom/datura/user/SimpleUserData.java @@ -15,6 +15,7 @@ import org.jetbrains.annotations.Nullable; import java.sql.SQLException; import java.util.UUID; +import java.util.concurrent.atomic.AtomicLong; public class SimpleUserData implements UserData { @@ -26,7 +27,7 @@ public class SimpleUserData implements UserData private boolean frozen; private boolean canInteract; private boolean caged; - private long balance; + private AtomicLong balance; private boolean transactionsFrozen; public SimpleUserData(final Player player) @@ -56,7 +57,7 @@ public class SimpleUserData implements UserData this.frozen = frozen; this.canInteract = canInteract; this.caged = caged; - this.balance = balance; + this.balance = new AtomicLong(balance); this.transactionsFrozen = transactionsFrozen; } @@ -215,24 +216,24 @@ public class SimpleUserData implements UserData @Override public long getBalance() { - return balance; + return balance.get(); } @Override public void addToBalance(long amount) { - this.balance += amount; + this.balance.addAndGet(amount); } @Override public void removeFromBalance(long amount) { - this.balance -= amount; + this.balance.addAndGet(-amount); } @Override public void setBalance(long newBalance) { - this.balance = newBalance; + this.balance.set(newBalance); } } From f366a91b36dd4e1b9732162a41c3b4540dc41407 Mon Sep 17 00:00:00 2001 From: Allink Date: Sat, 20 May 2023 05:36:43 +0100 Subject: [PATCH 10/22] Add transaction logging classes --- .../economy/SimpleLoggedTransactor.java | 37 ++++++++++++++++ .../economy/SimpleTransactionLogger.java | 43 +++++++++++++++++++ .../economy/TransactionLogger.java | 6 +++ 3 files changed, 86 insertions(+) create mode 100644 Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleLoggedTransactor.java create mode 100644 Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionLogger.java create mode 100644 Patchwork/src/main/java/me/totalfreedom/economy/TransactionLogger.java diff --git a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleLoggedTransactor.java b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleLoggedTransactor.java new file mode 100644 index 0000000..4354cea --- /dev/null +++ b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleLoggedTransactor.java @@ -0,0 +1,37 @@ +package me.totalfreedom.fossil.economy; + +import me.totalfreedom.economy.CompletedTransaction; +import me.totalfreedom.economy.Transaction; +import me.totalfreedom.economy.TransactionLogger; +import me.totalfreedom.economy.Transactor; + +public class SimpleLoggedTransactor implements Transactor +{ + private final Transactor transactor; + private final TransactionLogger transactionLogger; + + public SimpleLoggedTransactor() + { + this(new SimpleTransactor(), new SimpleTransactionLogger()); + } + + public SimpleLoggedTransactor(Transactor transactor, TransactionLogger transactionLogger) + { + this.transactor = transactor; + this.transactionLogger = transactionLogger; + } + + @Override + public CompletedTransaction handleTransaction(Transaction transaction) + { + CompletedTransaction completedTransaction = transactor.handleTransaction(transaction); + + transactionLogger.logTransaction(completedTransaction); + return completedTransaction; + } + + public TransactionLogger getTransactionLogger() + { + return this.transactionLogger; + } +} diff --git a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionLogger.java b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionLogger.java new file mode 100644 index 0000000..2f6d9cd --- /dev/null +++ b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionLogger.java @@ -0,0 +1,43 @@ +package me.totalfreedom.fossil.economy; + +import me.totalfreedom.audience.MutableAudienceForwarder; +import me.totalfreedom.economy.*; +import me.totalfreedom.utils.FreedomLogger; +import net.kyori.adventure.text.Component; +import org.bukkit.Bukkit; + +public class SimpleTransactionLogger implements TransactionLogger +{ + private MutableAudienceForwarder audience = MutableAudienceForwarder.from(FreedomLogger.getLogger("Fossil"), Bukkit.getConsoleSender()); + + @Override + public void logTransaction(CompletedTransaction completedTransaction) + { + StringBuilder transactionLoggingStatementBuilder = new StringBuilder(); + TransactionResult result = completedTransaction.getResult(); + boolean resultSuccess = result.isSuccessful(); + String resultMessage = result.getMessage(); + + Transaction transaction = completedTransaction.getTransaction(); + EconomicEntity source = transaction.getSource(); + EconomicEntity destination = transaction.getDestination(); + long transactionAmount = transaction.getTransferAmount(); + + transactionLoggingStatementBuilder.append(resultSuccess ? "Successful" : "Unsuccessful") + .append(" (") + .append(resultMessage) + .append(") ") + .append(" transaction between ") + .append(source.getName()) + .append(" ") + .append(destination.getName()) + .append(" where the volume of currency transferred was ") + .append("$") + .append(transactionAmount) + .append("."); + + Component message = Component.text(transactionLoggingStatementBuilder.toString()); + + audience.sendMessage(message); + } +} diff --git a/Patchwork/src/main/java/me/totalfreedom/economy/TransactionLogger.java b/Patchwork/src/main/java/me/totalfreedom/economy/TransactionLogger.java new file mode 100644 index 0000000..f8dce2d --- /dev/null +++ b/Patchwork/src/main/java/me/totalfreedom/economy/TransactionLogger.java @@ -0,0 +1,6 @@ +package me.totalfreedom.economy; + +public interface TransactionLogger +{ + void logTransaction(CompletedTransaction completedTransaction); +} From cad1ab8ec7a5e6cf1cd5af17a67d35a5bc0db326 Mon Sep 17 00:00:00 2001 From: Allink Date: Sat, 20 May 2023 05:42:17 +0100 Subject: [PATCH 11/22] Remove a few this references --- .../java/me/totalfreedom/datura/user/SimpleUserData.java | 8 ++++---- .../me/totalfreedom/fossil/economy/SimpleTransaction.java | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Datura/src/main/java/me/totalfreedom/datura/user/SimpleUserData.java b/Datura/src/main/java/me/totalfreedom/datura/user/SimpleUserData.java index fb3e825..556ec60 100644 --- a/Datura/src/main/java/me/totalfreedom/datura/user/SimpleUserData.java +++ b/Datura/src/main/java/me/totalfreedom/datura/user/SimpleUserData.java @@ -210,7 +210,7 @@ public class SimpleUserData implements UserData @Override public boolean areTransactionsFrozen() { - return this.transactionsFrozen; + return transactionsFrozen; } @Override @@ -222,18 +222,18 @@ public class SimpleUserData implements UserData @Override public void addToBalance(long amount) { - this.balance.addAndGet(amount); + balance.addAndGet(amount); } @Override public void removeFromBalance(long amount) { - this.balance.addAndGet(-amount); + balance.addAndGet(-amount); } @Override public void setBalance(long newBalance) { - this.balance.set(newBalance); + balance.set(newBalance); } } diff --git a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransaction.java b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransaction.java index 17e0a13..b65f8b6 100644 --- a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransaction.java +++ b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransaction.java @@ -27,25 +27,25 @@ public class SimpleTransaction implements Transaction @Override public EconomicEntity getSource() { - return this.source; + return source; } @Override public EconomicEntity getDestination() { - return this.destination; + return destination; } @Override public long getTransferAmount() { - return this.transferAmount.get(); + return transferAmount.get(); } @Override public long addBalance(long amount) { - return this.transferAmount.addAndGet(amount); + return transferAmount.addAndGet(amount); } @Override From cd5c42801d814902171e98d810da52a6c074b52e Mon Sep 17 00:00:00 2001 From: Allink Date: Sat, 20 May 2023 05:54:24 +0100 Subject: [PATCH 12/22] Rename transaction-related references of transfer amount to balance This is done for more consistency between methods. --- .../fossil/economy/SimpleTransaction.java | 14 +++++++------- .../fossil/economy/SimpleTransactionLogger.java | 2 +- .../fossil/economy/SimpleTransactor.java | 2 +- .../java/me/totalfreedom/economy/Transaction.java | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransaction.java b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransaction.java index b65f8b6..0e1ea2c 100644 --- a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransaction.java +++ b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransaction.java @@ -9,19 +9,19 @@ public class SimpleTransaction implements Transaction { private final EconomicEntity source; private final EconomicEntity destination; - private final AtomicLong transferAmount; + private final AtomicLong balance; - public SimpleTransaction(EconomicEntity source, EconomicEntity destination, long transferAmount) + public SimpleTransaction(EconomicEntity source, EconomicEntity destination, long balance) { this.source = source; this.destination = destination; - this.transferAmount = new AtomicLong(transferAmount); + this.balance = new AtomicLong(balance); } @Override public Transaction copy() { - return new SimpleTransaction(source, destination, transferAmount.get()); + return new SimpleTransaction(source, destination, balance.get()); } @Override @@ -37,15 +37,15 @@ public class SimpleTransaction implements Transaction } @Override - public long getTransferAmount() + public long getBalance() { - return transferAmount.get(); + return balance.get(); } @Override public long addBalance(long amount) { - return transferAmount.addAndGet(amount); + return balance.addAndGet(amount); } @Override diff --git a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionLogger.java b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionLogger.java index 2f6d9cd..6f7614f 100644 --- a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionLogger.java +++ b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionLogger.java @@ -21,7 +21,7 @@ public class SimpleTransactionLogger implements TransactionLogger Transaction transaction = completedTransaction.getTransaction(); EconomicEntity source = transaction.getSource(); EconomicEntity destination = transaction.getDestination(); - long transactionAmount = transaction.getTransferAmount(); + long transactionAmount = transaction.getBalance(); transactionLoggingStatementBuilder.append(resultSuccess ? "Successful" : "Unsuccessful") .append(" (") diff --git a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactor.java b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactor.java index b0fedad..913ded3 100644 --- a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactor.java +++ b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactor.java @@ -16,7 +16,7 @@ public class SimpleTransactor implements Transactor return new SimpleCompletedTransaction(transaction, SimpleTransactionResult.UNAUTHORIZED); } - long transactionAmount = transaction.getTransferAmount(); + long transactionAmount = transaction.getBalance(); if (transactionAmount >= 0) { diff --git a/Patchwork/src/main/java/me/totalfreedom/economy/Transaction.java b/Patchwork/src/main/java/me/totalfreedom/economy/Transaction.java index d61b3c0..bcafa51 100644 --- a/Patchwork/src/main/java/me/totalfreedom/economy/Transaction.java +++ b/Patchwork/src/main/java/me/totalfreedom/economy/Transaction.java @@ -8,7 +8,7 @@ public interface Transaction EconomicEntity getDestination(); - long getTransferAmount(); + long getBalance(); long addBalance(final long amount); From 042960473754a19352547699352a654b0b2e7dbc Mon Sep 17 00:00:00 2001 From: Allink Date: Sat, 20 May 2023 05:55:26 +0100 Subject: [PATCH 13/22] Add method for directly setting a transaction's balance --- .../me/totalfreedom/fossil/economy/SimpleTransaction.java | 6 ++++++ .../src/main/java/me/totalfreedom/economy/Transaction.java | 2 ++ 2 files changed, 8 insertions(+) diff --git a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransaction.java b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransaction.java index 0e1ea2c..8fb9b8c 100644 --- a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransaction.java +++ b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransaction.java @@ -53,4 +53,10 @@ public class SimpleTransaction implements Transaction { return this.addBalance(-amount); } + + @Override + public void setBalance(long newBalance) + { + balance.set(newBalance); + } } diff --git a/Patchwork/src/main/java/me/totalfreedom/economy/Transaction.java b/Patchwork/src/main/java/me/totalfreedom/economy/Transaction.java index bcafa51..fc094cc 100644 --- a/Patchwork/src/main/java/me/totalfreedom/economy/Transaction.java +++ b/Patchwork/src/main/java/me/totalfreedom/economy/Transaction.java @@ -13,4 +13,6 @@ public interface Transaction long addBalance(final long amount); long removeBalance(final long amount); + + void setBalance(final long newBalance); } From a598434bf90ffc579cea67886d1e360a39e3130b Mon Sep 17 00:00:00 2001 From: Allink Date: Sat, 20 May 2023 05:55:51 +0100 Subject: [PATCH 14/22] Refactor transaction results to be more consistent --- .../totalfreedom/fossil/economy/SimpleTransactionResult.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionResult.java b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionResult.java index 55623a3..258ae84 100644 --- a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionResult.java +++ b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionResult.java @@ -8,8 +8,8 @@ public class SimpleTransactionResult implements TransactionResult { public static final TransactionResult SUCCESSFUL = new SimpleTransactionResult("Successful transaction.", true); public static final TransactionResult UNAUTHORIZED = new SimpleTransactionResult("Unauthorized transaction.", false); - public static final TransactionResult AMOUNT_TOO_SMALL = new SimpleTransactionResult("Transaction transfer amount too small.", false); - public static final TransactionResult INSUFFICIENT_FUNDS = new SimpleTransactionResult("The source has insufficient funds to carry out this transaction.", false); + public static final TransactionResult AMOUNT_TOO_SMALL = new SimpleTransactionResult("Transaction balance too small.", false); + public static final TransactionResult INSUFFICIENT_FUNDS = new SimpleTransactionResult("The source has an insufficient balance to carry out this transaction.", false); private final String message; private final Component component; private final boolean successful; From cb208c710f777ff6433d85c7f5389b38bc86413b Mon Sep 17 00:00:00 2001 From: Allink Date: Sat, 20 May 2023 06:08:17 +0100 Subject: [PATCH 15/22] Refactor transaction balance methods to be more in-line with EconomicEntityData --- .../me/totalfreedom/fossil/economy/SimpleTransaction.java | 6 +++--- .../src/main/java/me/totalfreedom/economy/Transaction.java | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransaction.java b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransaction.java index 8fb9b8c..958634f 100644 --- a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransaction.java +++ b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransaction.java @@ -43,15 +43,15 @@ public class SimpleTransaction implements Transaction } @Override - public long addBalance(long amount) + public long addToBalance(long amount) { return balance.addAndGet(amount); } @Override - public long removeBalance(long amount) + public long removeFromBalance(long amount) { - return this.addBalance(-amount); + return this.addToBalance(-amount); } @Override diff --git a/Patchwork/src/main/java/me/totalfreedom/economy/Transaction.java b/Patchwork/src/main/java/me/totalfreedom/economy/Transaction.java index fc094cc..3413976 100644 --- a/Patchwork/src/main/java/me/totalfreedom/economy/Transaction.java +++ b/Patchwork/src/main/java/me/totalfreedom/economy/Transaction.java @@ -10,9 +10,9 @@ public interface Transaction long getBalance(); - long addBalance(final long amount); + long addToBalance(final long amount); - long removeBalance(final long amount); + long removeFromBalance(final long amount); void setBalance(final long newBalance); } From 7817b0770c5ff458f1c84146c414edbbf591a9f9 Mon Sep 17 00:00:00 2001 From: Allink Date: Sat, 20 May 2023 06:11:24 +0100 Subject: [PATCH 16/22] Refactor arithmetic operations in EconomicEntityData to be more in-line with Transaction --- .../java/me/totalfreedom/datura/user/SimpleUserData.java | 8 ++++---- .../java/me/totalfreedom/economy/EconomicEntityData.java | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Datura/src/main/java/me/totalfreedom/datura/user/SimpleUserData.java b/Datura/src/main/java/me/totalfreedom/datura/user/SimpleUserData.java index 556ec60..82d086d 100644 --- a/Datura/src/main/java/me/totalfreedom/datura/user/SimpleUserData.java +++ b/Datura/src/main/java/me/totalfreedom/datura/user/SimpleUserData.java @@ -220,15 +220,15 @@ public class SimpleUserData implements UserData } @Override - public void addToBalance(long amount) + public long addToBalance(long amount) { - balance.addAndGet(amount); + return balance.addAndGet(amount); } @Override - public void removeFromBalance(long amount) + public long removeFromBalance(long amount) { - balance.addAndGet(-amount); + return balance.addAndGet(-amount); } @Override diff --git a/Patchwork/src/main/java/me/totalfreedom/economy/EconomicEntityData.java b/Patchwork/src/main/java/me/totalfreedom/economy/EconomicEntityData.java index 356daac..308a6c0 100644 --- a/Patchwork/src/main/java/me/totalfreedom/economy/EconomicEntityData.java +++ b/Patchwork/src/main/java/me/totalfreedom/economy/EconomicEntityData.java @@ -6,9 +6,9 @@ public interface EconomicEntityData long getBalance(); - void addToBalance(final long amount); + long addToBalance(final long amount); - void removeFromBalance(final long amount); + long removeFromBalance(final long amount); void setBalance(final long newBalance); } From 18353deb13d952e81755bd7981825812bb3fd7ba Mon Sep 17 00:00:00 2001 From: Allink Date: Sat, 20 May 2023 06:35:58 +0100 Subject: [PATCH 17/22] Remove unnecessary console sender audience from simple transaction logger --- .../me/totalfreedom/fossil/economy/SimpleTransactionLogger.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionLogger.java b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionLogger.java index 6f7614f..71e6230 100644 --- a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionLogger.java +++ b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionLogger.java @@ -8,7 +8,7 @@ import org.bukkit.Bukkit; public class SimpleTransactionLogger implements TransactionLogger { - private MutableAudienceForwarder audience = MutableAudienceForwarder.from(FreedomLogger.getLogger("Fossil"), Bukkit.getConsoleSender()); + private MutableAudienceForwarder audience = MutableAudienceForwarder.from(FreedomLogger.getLogger("Fossil")); @Override public void logTransaction(CompletedTransaction completedTransaction) From b98b0870b137c684559f95185fbcd5db8875d20c Mon Sep 17 00:00:00 2001 From: Allink Date: Sat, 20 May 2023 06:36:16 +0100 Subject: [PATCH 18/22] Finalize MutableAudienceForwarder instance inside of SimpleTransactionLogger --- .../me/totalfreedom/fossil/economy/SimpleTransactionLogger.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionLogger.java b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionLogger.java index 71e6230..217af26 100644 --- a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionLogger.java +++ b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionLogger.java @@ -8,7 +8,7 @@ import org.bukkit.Bukkit; public class SimpleTransactionLogger implements TransactionLogger { - private MutableAudienceForwarder audience = MutableAudienceForwarder.from(FreedomLogger.getLogger("Fossil")); + private final MutableAudienceForwarder audience = MutableAudienceForwarder.from(FreedomLogger.getLogger("Fossil")); @Override public void logTransaction(CompletedTransaction completedTransaction) From 95df78da6f7064724857de76a87b8f5e329893d3 Mon Sep 17 00:00:00 2001 From: Allink Date: Sat, 20 May 2023 06:37:12 +0100 Subject: [PATCH 19/22] Expose MutableAudienceForwarder in SimpleTransactionLogger This will add the ability for us to add audiences to the MutableAudienceForwarder inside of SimpleTransactionLogger, which will make TransactionSpy much easier. --- .../fossil/economy/SimpleTransactionLogger.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionLogger.java b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionLogger.java index 217af26..c8dec4f 100644 --- a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionLogger.java +++ b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionLogger.java @@ -4,7 +4,6 @@ import me.totalfreedom.audience.MutableAudienceForwarder; import me.totalfreedom.economy.*; import me.totalfreedom.utils.FreedomLogger; import net.kyori.adventure.text.Component; -import org.bukkit.Bukkit; public class SimpleTransactionLogger implements TransactionLogger { @@ -40,4 +39,9 @@ public class SimpleTransactionLogger implements TransactionLogger audience.sendMessage(message); } + + public MutableAudienceForwarder getAudienceForwarder() + { + return audience; + } } From 036ddf3e048214ed74bacd2e3f990b45dbab4525 Mon Sep 17 00:00:00 2001 From: Allink Date: Sat, 20 May 2023 20:20:39 +0100 Subject: [PATCH 20/22] Add mutable & immutable transaction interfaces and implementations, replacing copy() --- .../economy/SimpleCompletedTransaction.java | 35 ++++++++++++++----- .../economy/SimpleLoggedTransactor.java | 4 +-- .../economy/SimpleMutableTransaction.java | 30 ++++++++++++++++ .../fossil/economy/SimpleTransaction.java | 26 +------------- .../fossil/economy/SimpleTransactor.java | 7 ++-- .../economy/CompletedTransaction.java | 3 +- .../economy/MutableTransaction.java | 13 +++++++ .../me/totalfreedom/economy/Transaction.java | 7 ---- .../me/totalfreedom/economy/Transactor.java | 2 +- 9 files changed, 77 insertions(+), 50 deletions(-) create mode 100644 Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleMutableTransaction.java create mode 100644 Patchwork/src/main/java/me/totalfreedom/economy/MutableTransaction.java diff --git a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleCompletedTransaction.java b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleCompletedTransaction.java index 9080019..b7ba257 100644 --- a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleCompletedTransaction.java +++ b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleCompletedTransaction.java @@ -1,30 +1,47 @@ package me.totalfreedom.fossil.economy; import me.totalfreedom.economy.CompletedTransaction; +import me.totalfreedom.economy.EconomicEntity; import me.totalfreedom.economy.Transaction; import me.totalfreedom.economy.TransactionResult; public class SimpleCompletedTransaction implements CompletedTransaction { - private final Transaction transaction; private final TransactionResult transactionResult; + private final EconomicEntity source; + private final EconomicEntity destination; + private final long balance; public SimpleCompletedTransaction(Transaction transaction, TransactionResult transactionResult) { - this.transaction = transaction.copy(); + + this.source = transaction.getSource(); + this.destination = transaction.getDestination(); + this.balance = transaction.getBalance(); this.transactionResult = transactionResult; } - - @Override - public Transaction getTransaction() - { - return transaction.copy(); - } - @Override public TransactionResult getResult() { return transactionResult; } + + @Override + public EconomicEntity getSource() + { + return source; + } + + @Override + public EconomicEntity getDestination() + { + return destination; + } + + @Override + public long getBalance() + { + return balance; + } } diff --git a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleLoggedTransactor.java b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleLoggedTransactor.java index 4354cea..4bf35ca 100644 --- a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleLoggedTransactor.java +++ b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleLoggedTransactor.java @@ -1,7 +1,7 @@ package me.totalfreedom.fossil.economy; import me.totalfreedom.economy.CompletedTransaction; -import me.totalfreedom.economy.Transaction; +import me.totalfreedom.economy.MutableTransaction; import me.totalfreedom.economy.TransactionLogger; import me.totalfreedom.economy.Transactor; @@ -22,7 +22,7 @@ public class SimpleLoggedTransactor implements Transactor } @Override - public CompletedTransaction handleTransaction(Transaction transaction) + public CompletedTransaction handleTransaction(MutableTransaction transaction) { CompletedTransaction completedTransaction = transactor.handleTransaction(transaction); diff --git a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleMutableTransaction.java b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleMutableTransaction.java new file mode 100644 index 0000000..c99cb65 --- /dev/null +++ b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleMutableTransaction.java @@ -0,0 +1,30 @@ +package me.totalfreedom.fossil.economy; + +import me.totalfreedom.economy.EconomicEntity; +import me.totalfreedom.economy.MutableTransaction; + +public class SimpleMutableTransaction extends SimpleTransaction implements MutableTransaction +{ + public SimpleMutableTransaction(EconomicEntity source, EconomicEntity destination, long balance) + { + super(source, destination, balance); + } + + @Override + public long addToBalance(long amount) + { + return balance.addAndGet(amount); + } + + @Override + public long removeFromBalance(long amount) + { + return this.addToBalance(-amount); + } + + @Override + public void setBalance(long newBalance) + { + balance.set(newBalance); + } +} diff --git a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransaction.java b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransaction.java index 958634f..4e3e008 100644 --- a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransaction.java +++ b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransaction.java @@ -9,7 +9,7 @@ public class SimpleTransaction implements Transaction { private final EconomicEntity source; private final EconomicEntity destination; - private final AtomicLong balance; + protected final AtomicLong balance; public SimpleTransaction(EconomicEntity source, EconomicEntity destination, long balance) { @@ -18,12 +18,6 @@ public class SimpleTransaction implements Transaction this.balance = new AtomicLong(balance); } - @Override - public Transaction copy() - { - return new SimpleTransaction(source, destination, balance.get()); - } - @Override public EconomicEntity getSource() { @@ -41,22 +35,4 @@ public class SimpleTransaction implements Transaction { return balance.get(); } - - @Override - public long addToBalance(long amount) - { - return balance.addAndGet(amount); - } - - @Override - public long removeFromBalance(long amount) - { - return this.addToBalance(-amount); - } - - @Override - public void setBalance(long newBalance) - { - balance.set(newBalance); - } } diff --git a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactor.java b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactor.java index 913ded3..735571e 100644 --- a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactor.java +++ b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactor.java @@ -5,9 +5,8 @@ import me.totalfreedom.economy.*; public class SimpleTransactor implements Transactor { @Override - public CompletedTransaction handleTransaction(Transaction transaction) + public CompletedTransaction handleTransaction(MutableTransaction transaction) { - Transaction transactionCopy = transaction.copy(); EconomicEntity source = transaction.getSource(); EconomicEntityData sourceData = source.getEconomicData(); @@ -28,7 +27,7 @@ public class SimpleTransactor implements Transactor if (diff > 0) { - return new SimpleCompletedTransaction(transactionCopy, SimpleTransactionResult.INSUFFICIENT_FUNDS); + return new SimpleCompletedTransaction(transaction, SimpleTransactionResult.INSUFFICIENT_FUNDS); } EconomicEntity destination = transaction.getDestination(); @@ -42,6 +41,6 @@ public class SimpleTransactor implements Transactor sourceData.removeFromBalance(transactionAmount); destinationData.addToBalance(transactionAmount); - return new SimpleCompletedTransaction(transactionCopy, SimpleTransactionResult.SUCCESSFUL); + return new SimpleCompletedTransaction(transaction, SimpleTransactionResult.SUCCESSFUL); } } diff --git a/Patchwork/src/main/java/me/totalfreedom/economy/CompletedTransaction.java b/Patchwork/src/main/java/me/totalfreedom/economy/CompletedTransaction.java index 5c67cfa..7b58dfd 100644 --- a/Patchwork/src/main/java/me/totalfreedom/economy/CompletedTransaction.java +++ b/Patchwork/src/main/java/me/totalfreedom/economy/CompletedTransaction.java @@ -1,8 +1,7 @@ package me.totalfreedom.economy; -public interface CompletedTransaction +public interface CompletedTransaction extends Transaction { - Transaction getTransaction(); TransactionResult getResult(); } diff --git a/Patchwork/src/main/java/me/totalfreedom/economy/MutableTransaction.java b/Patchwork/src/main/java/me/totalfreedom/economy/MutableTransaction.java new file mode 100644 index 0000000..8548fa7 --- /dev/null +++ b/Patchwork/src/main/java/me/totalfreedom/economy/MutableTransaction.java @@ -0,0 +1,13 @@ +package me.totalfreedom.economy; + +/** + * Please ensure that all modifications of {@link MutableTransaction} happen BEFORE it is passed to a {@link Transactor} implementation + */ +public interface MutableTransaction extends Transaction +{ + long addToBalance(final long amount); + + long removeFromBalance(final long amount); + + void setBalance(final long newBalance); +} diff --git a/Patchwork/src/main/java/me/totalfreedom/economy/Transaction.java b/Patchwork/src/main/java/me/totalfreedom/economy/Transaction.java index 3413976..eb0e310 100644 --- a/Patchwork/src/main/java/me/totalfreedom/economy/Transaction.java +++ b/Patchwork/src/main/java/me/totalfreedom/economy/Transaction.java @@ -2,17 +2,10 @@ package me.totalfreedom.economy; public interface Transaction { - Transaction copy(); - EconomicEntity getSource(); EconomicEntity getDestination(); long getBalance(); - long addToBalance(final long amount); - - long removeFromBalance(final long amount); - - void setBalance(final long newBalance); } diff --git a/Patchwork/src/main/java/me/totalfreedom/economy/Transactor.java b/Patchwork/src/main/java/me/totalfreedom/economy/Transactor.java index be078ba..8fd9c47 100644 --- a/Patchwork/src/main/java/me/totalfreedom/economy/Transactor.java +++ b/Patchwork/src/main/java/me/totalfreedom/economy/Transactor.java @@ -2,5 +2,5 @@ package me.totalfreedom.economy; public interface Transactor { - CompletedTransaction handleTransaction(Transaction transaction); + CompletedTransaction handleTransaction(MutableTransaction transaction); } From aadd5d57aa3cf6b6510127391ab5e2ef6f729997 Mon Sep 17 00:00:00 2001 From: Allink Date: Sat, 20 May 2023 20:22:46 +0100 Subject: [PATCH 21/22] Fix transaction logger implementation & remove unnecessary StringBuilder append --- .../fossil/economy/SimpleTransactionLogger.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionLogger.java b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionLogger.java index c8dec4f..e53551b 100644 --- a/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionLogger.java +++ b/Fossil/src/main/java/me/totalfreedom/fossil/economy/SimpleTransactionLogger.java @@ -17,10 +17,9 @@ public class SimpleTransactionLogger implements TransactionLogger boolean resultSuccess = result.isSuccessful(); String resultMessage = result.getMessage(); - Transaction transaction = completedTransaction.getTransaction(); - EconomicEntity source = transaction.getSource(); - EconomicEntity destination = transaction.getDestination(); - long transactionAmount = transaction.getBalance(); + EconomicEntity source = completedTransaction.getSource(); + EconomicEntity destination = completedTransaction.getDestination(); + long transactionAmount = completedTransaction.getBalance(); transactionLoggingStatementBuilder.append(resultSuccess ? "Successful" : "Unsuccessful") .append(" (") @@ -30,8 +29,7 @@ public class SimpleTransactionLogger implements TransactionLogger .append(source.getName()) .append(" ") .append(destination.getName()) - .append(" where the volume of currency transferred was ") - .append("$") + .append(" where the volume of currency transferred was $") .append(transactionAmount) .append("."); From 997fa2a4a90258ebeb27e734b36b450a0900f64e Mon Sep 17 00:00:00 2001 From: Paldiu Date: Sun, 21 May 2023 19:05:43 -0500 Subject: [PATCH 22/22] Update README.md --- README.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/README.md b/README.md index 4b7e594..8d9dc51 100644 --- a/README.md +++ b/README.md @@ -55,3 +55,43 @@ This proof-of-concept also uses the following libraries: [](https://github.com/VideoGameSmash12)
[](https://github.com/allinkdev) + +# To Do List +Patchwork: +- [x] Logging System +- [x] SQL API +- [x] Economy API +- [ ] Command API +- [ ] Particle API +- [x] User API +- [ ] Ban API +- [x] Service API +- [x] Task API +- [x] Permissions API +- [ ] Configuration API +- [ ] Event API + +Datura: +- [ ] Permission Handling +- [ ] Permission Registration & Assignment +- [ ] SQL Data Handling +- [ ] Configuration Implementations +- [ ] User Data Implementations +- [ ] Banning Implementation +- [ ] Punishment Systems (e.x. Locker, Halter, Muter, Cager) + +Fossil: +- [x] Economy Implementation +- [ ] Particle Implementation / Trails +- [ ] Command Implementations +- [ ] Implement a shop for the economy +- [ ] Chat reaction / game system +- [ ] Jumppads + +Corvo: +- [ ] Service Implementation +- [ ] Service Handling +- [ ] Task Implementation +- [ ] Task Management +- [ ] Event (Project) Implementations +- [ ] Listener (Bukkit) Implementations