mirror of
https://github.com/SimplexDevelopment/FreedomNetworkSuite.git
synced 2024-11-14 05:03:33 +00:00
Merge pull request #5 from SimplexDevelopment/feat/economy-outline
Implement outline of the economy system
This commit is contained in:
commit
82c8aed5ba
@ -15,6 +15,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
public class SimpleUserData implements UserData
|
public class SimpleUserData implements UserData
|
||||||
{
|
{
|
||||||
@ -26,6 +27,8 @@ public class SimpleUserData implements UserData
|
|||||||
private boolean frozen;
|
private boolean frozen;
|
||||||
private boolean canInteract;
|
private boolean canInteract;
|
||||||
private boolean caged;
|
private boolean caged;
|
||||||
|
private AtomicLong balance;
|
||||||
|
private boolean transactionsFrozen;
|
||||||
|
|
||||||
public SimpleUserData(final Player player)
|
public SimpleUserData(final Player player)
|
||||||
{
|
{
|
||||||
@ -42,7 +45,9 @@ public class SimpleUserData implements UserData
|
|||||||
final long playtime,
|
final long playtime,
|
||||||
final boolean frozen,
|
final boolean frozen,
|
||||||
final boolean canInteract,
|
final boolean canInteract,
|
||||||
final boolean caged)
|
final boolean caged,
|
||||||
|
final long balance,
|
||||||
|
final boolean transactionsFrozen)
|
||||||
{
|
{
|
||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
this.username = username;
|
this.username = username;
|
||||||
@ -52,6 +57,8 @@ public class SimpleUserData implements UserData
|
|||||||
this.frozen = frozen;
|
this.frozen = frozen;
|
||||||
this.canInteract = canInteract;
|
this.canInteract = canInteract;
|
||||||
this.caged = caged;
|
this.caged = caged;
|
||||||
|
this.balance = new AtomicLong(balance);
|
||||||
|
this.transactionsFrozen = transactionsFrozen;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SimpleUserData fromSQL(SQL sql, String uuid)
|
public static SimpleUserData fromSQL(SQL sql, String uuid)
|
||||||
@ -82,7 +89,9 @@ public class SimpleUserData implements UserData
|
|||||||
boolean frozen = result.getBoolean("frozen");
|
boolean frozen = result.getBoolean("frozen");
|
||||||
boolean canInteract = result.getBoolean("canInteract");
|
boolean canInteract = result.getBoolean("canInteract");
|
||||||
boolean caged = result.getBoolean("caged");
|
boolean caged = result.getBoolean("caged");
|
||||||
return new SimpleUserData(u, username, user, group, playtime, frozen, canInteract, caged);
|
long balance = result.getLong("balance");
|
||||||
|
boolean transactionsFrozen = result.getBoolean("transactionsFrozen");
|
||||||
|
return new SimpleUserData(u, username, user, group, playtime, frozen, canInteract, caged, balance, transactionsFrozen);
|
||||||
}
|
}
|
||||||
} catch (SQLException ex)
|
} catch (SQLException ex)
|
||||||
{
|
{
|
||||||
@ -197,4 +206,34 @@ public class SimpleUserData implements UserData
|
|||||||
{
|
{
|
||||||
this.caged = caged;
|
this.caged = caged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean areTransactionsFrozen()
|
||||||
|
{
|
||||||
|
return transactionsFrozen;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getBalance()
|
||||||
|
{
|
||||||
|
return balance.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long addToBalance(long amount)
|
||||||
|
{
|
||||||
|
return balance.addAndGet(amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long removeFromBalance(long amount)
|
||||||
|
{
|
||||||
|
return balance.addAndGet(-amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBalance(long newBalance)
|
||||||
|
{
|
||||||
|
balance.set(newBalance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +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 TransactionResult transactionResult;
|
||||||
|
private final EconomicEntity source;
|
||||||
|
private final EconomicEntity destination;
|
||||||
|
private final long balance;
|
||||||
|
|
||||||
|
public SimpleCompletedTransaction(Transaction transaction, TransactionResult transactionResult)
|
||||||
|
{
|
||||||
|
|
||||||
|
this.source = transaction.getSource();
|
||||||
|
this.destination = transaction.getDestination();
|
||||||
|
this.balance = transaction.getBalance();
|
||||||
|
this.transactionResult = transactionResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TransactionResult getResult()
|
||||||
|
{
|
||||||
|
return transactionResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EconomicEntity getSource()
|
||||||
|
{
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EconomicEntity getDestination()
|
||||||
|
{
|
||||||
|
return destination;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getBalance()
|
||||||
|
{
|
||||||
|
return balance;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package me.totalfreedom.fossil.economy;
|
||||||
|
|
||||||
|
import me.totalfreedom.economy.CompletedTransaction;
|
||||||
|
import me.totalfreedom.economy.MutableTransaction;
|
||||||
|
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(MutableTransaction transaction)
|
||||||
|
{
|
||||||
|
CompletedTransaction completedTransaction = transactor.handleTransaction(transaction);
|
||||||
|
|
||||||
|
transactionLogger.logTransaction(completedTransaction);
|
||||||
|
return completedTransaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TransactionLogger getTransactionLogger()
|
||||||
|
{
|
||||||
|
return this.transactionLogger;
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
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;
|
||||||
|
protected final AtomicLong balance;
|
||||||
|
|
||||||
|
public SimpleTransaction(EconomicEntity source, EconomicEntity destination, long balance)
|
||||||
|
{
|
||||||
|
this.source = source;
|
||||||
|
this.destination = destination;
|
||||||
|
this.balance = new AtomicLong(balance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EconomicEntity getSource()
|
||||||
|
{
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EconomicEntity getDestination()
|
||||||
|
{
|
||||||
|
return destination;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getBalance()
|
||||||
|
{
|
||||||
|
return balance.get();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
public class SimpleTransactionLogger implements TransactionLogger
|
||||||
|
{
|
||||||
|
private final MutableAudienceForwarder audience = MutableAudienceForwarder.from(FreedomLogger.getLogger("Fossil"));
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void logTransaction(CompletedTransaction completedTransaction)
|
||||||
|
{
|
||||||
|
StringBuilder transactionLoggingStatementBuilder = new StringBuilder();
|
||||||
|
TransactionResult result = completedTransaction.getResult();
|
||||||
|
boolean resultSuccess = result.isSuccessful();
|
||||||
|
String resultMessage = result.getMessage();
|
||||||
|
|
||||||
|
EconomicEntity source = completedTransaction.getSource();
|
||||||
|
EconomicEntity destination = completedTransaction.getDestination();
|
||||||
|
long transactionAmount = completedTransaction.getBalance();
|
||||||
|
|
||||||
|
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(transactionAmount)
|
||||||
|
.append(".");
|
||||||
|
|
||||||
|
Component message = Component.text(transactionLoggingStatementBuilder.toString());
|
||||||
|
|
||||||
|
audience.sendMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MutableAudienceForwarder getAudienceForwarder()
|
||||||
|
{
|
||||||
|
return audience;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
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
|
||||||
|
{
|
||||||
|
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 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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package me.totalfreedom.fossil.economy;
|
||||||
|
|
||||||
|
import me.totalfreedom.economy.*;
|
||||||
|
|
||||||
|
public class SimpleTransactor implements Transactor
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public CompletedTransaction handleTransaction(MutableTransaction transaction)
|
||||||
|
{
|
||||||
|
EconomicEntity source = transaction.getSource();
|
||||||
|
EconomicEntityData sourceData = source.getEconomicData();
|
||||||
|
|
||||||
|
if (sourceData.areTransactionsFrozen())
|
||||||
|
{
|
||||||
|
return new SimpleCompletedTransaction(transaction, SimpleTransactionResult.UNAUTHORIZED);
|
||||||
|
}
|
||||||
|
|
||||||
|
long transactionAmount = transaction.getBalance();
|
||||||
|
|
||||||
|
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(transaction, 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(transaction, SimpleTransactionResult.SUCCESSFUL);
|
||||||
|
}
|
||||||
|
}
|
@ -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.
|
||||||
|
* <p>
|
||||||
|
* 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<Audience> 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<? super Audience> filter)
|
||||||
|
{
|
||||||
|
return audiences.stream()
|
||||||
|
.filter(filter)
|
||||||
|
.findFirst()
|
||||||
|
.orElseThrow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void forEachAudience(@NotNull Consumer<? super Audience> 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 <T> void sendTitlePart(@NotNull TitlePart<T> 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));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package me.totalfreedom.economy;
|
||||||
|
|
||||||
|
public interface CompletedTransaction extends Transaction
|
||||||
|
{
|
||||||
|
|
||||||
|
TransactionResult getResult();
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package me.totalfreedom.economy;
|
||||||
|
|
||||||
|
public interface EconomicEntity
|
||||||
|
{
|
||||||
|
EconomicEntityData getEconomicData();
|
||||||
|
|
||||||
|
String getName();
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package me.totalfreedom.economy;
|
||||||
|
|
||||||
|
public interface EconomicEntityData
|
||||||
|
{
|
||||||
|
boolean areTransactionsFrozen();
|
||||||
|
|
||||||
|
long getBalance();
|
||||||
|
|
||||||
|
long addToBalance(final long amount);
|
||||||
|
|
||||||
|
long removeFromBalance(final long amount);
|
||||||
|
|
||||||
|
void setBalance(final long newBalance);
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package me.totalfreedom.economy;
|
||||||
|
|
||||||
|
public interface Transaction
|
||||||
|
{
|
||||||
|
EconomicEntity getSource();
|
||||||
|
|
||||||
|
EconomicEntity getDestination();
|
||||||
|
|
||||||
|
long getBalance();
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
package me.totalfreedom.economy;
|
||||||
|
|
||||||
|
public interface TransactionLogger
|
||||||
|
{
|
||||||
|
void logTransaction(CompletedTransaction completedTransaction);
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package me.totalfreedom.economy;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
|
||||||
|
public interface TransactionResult
|
||||||
|
{
|
||||||
|
String getMessage();
|
||||||
|
|
||||||
|
boolean isSuccessful();
|
||||||
|
|
||||||
|
Component getComponent();
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
package me.totalfreedom.economy;
|
||||||
|
|
||||||
|
public interface Transactor
|
||||||
|
{
|
||||||
|
CompletedTransaction handleTransaction(MutableTransaction transaction);
|
||||||
|
}
|
@ -1,10 +1,25 @@
|
|||||||
package me.totalfreedom.user;
|
package me.totalfreedom.user;
|
||||||
|
|
||||||
|
import me.totalfreedom.economy.EconomicEntity;
|
||||||
|
import me.totalfreedom.economy.EconomicEntityData;
|
||||||
import me.totalfreedom.security.PermissionHolder;
|
import me.totalfreedom.security.PermissionHolder;
|
||||||
import net.kyori.adventure.text.Component;
|
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();
|
UserData getUserData();
|
||||||
|
|
||||||
Component getDisplayName();
|
Component getDisplayName();
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
package me.totalfreedom.user;
|
package me.totalfreedom.user;
|
||||||
|
|
||||||
|
import me.totalfreedom.economy.EconomicEntityData;
|
||||||
import me.totalfreedom.security.Group;
|
import me.totalfreedom.security.Group;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public interface UserData
|
public interface UserData extends EconomicEntityData
|
||||||
{
|
{
|
||||||
@NotNull UUID getUniqueId();
|
@NotNull UUID getUniqueId();
|
||||||
|
|
||||||
|
@ -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<Component> supplier)
|
||||||
|
{
|
||||||
|
return toPlainText(supplier.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Supplier<String> supplyPlainText(Supplier<Component> supplier)
|
||||||
|
{
|
||||||
|
return new StringRepresentationSupplier(supplier.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Supplier<String> supplyPlainText(Component component)
|
||||||
|
{
|
||||||
|
return new StringRepresentationSupplier(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
private record StringRepresentationSupplier(Component component) implements Supplier<String>
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public String get()
|
||||||
|
{
|
||||||
|
return PLAIN_TEXT_COMPONENT_SERIALIZER.serialize(component);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,12 +1,17 @@
|
|||||||
package me.totalfreedom.utils;
|
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.Component;
|
||||||
|
import net.kyori.adventure.text.ComponentLike;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class FreedomLogger
|
public class FreedomLogger implements Audience
|
||||||
{
|
{
|
||||||
private final Logger logger;
|
private final Logger logger;
|
||||||
private boolean debug = false;
|
private boolean debug = false;
|
||||||
@ -36,6 +41,20 @@ public class FreedomLogger
|
|||||||
logger.info(message);
|
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,
|
* This method allows you to log a message to the console,
|
||||||
* while also returning a Component that could be used to
|
* while also returning a Component that could be used to
|
||||||
@ -50,6 +69,19 @@ public class FreedomLogger
|
|||||||
return Component.text(message.get());
|
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> component)
|
||||||
|
{
|
||||||
|
return this.infoComponent(component.get());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method allows you to log a warning to the console.
|
* This method allows you to log a warning to the console.
|
||||||
*
|
*
|
||||||
@ -60,6 +92,18 @@ public class FreedomLogger
|
|||||||
logger.warn(message);
|
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.
|
* This method logs an error message to the console.
|
||||||
* It is highly recommended to deconstruct the stack trace and pass it
|
* It is highly recommended to deconstruct the stack trace and pass it
|
||||||
@ -72,6 +116,20 @@ public class FreedomLogger
|
|||||||
logger.error(message);
|
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.
|
* This method allows you to log an exception directly to the console.
|
||||||
*
|
*
|
||||||
@ -98,6 +156,19 @@ public class FreedomLogger
|
|||||||
return Component.text(message.get());
|
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> component)
|
||||||
|
{
|
||||||
|
return this.errorComponent(component.get());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method allows you to log a debug message to the console.
|
* This method allows you to log a debug message to the console.
|
||||||
* This method will only log if debug mode is enabled.
|
* This method will only log if debug mode is enabled.
|
||||||
@ -110,6 +181,21 @@ public class FreedomLogger
|
|||||||
logger.debug(message);
|
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,
|
* This method allows you to log a debug message to the console,
|
||||||
* while also returning a Component that could be used to
|
* while also returning a Component that could be used to
|
||||||
@ -128,4 +214,59 @@ public class FreedomLogger
|
|||||||
}
|
}
|
||||||
return Component.empty();
|
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> component)
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
return this.debugComponent(component.get());
|
||||||
|
}
|
||||||
|
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.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user