Merge branch 'kitchen-sink' into banning-update

This commit is contained in:
Paldiu 2023-05-21 19:29:17 -05:00 committed by GitHub
commit 4dd4fa6ad1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 899 additions and 5 deletions

View File

@ -16,6 +16,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
{ {
@ -28,6 +29,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)
{ {
@ -46,7 +49,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;
@ -56,6 +61,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)
@ -86,7 +93,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)
{ {
@ -207,4 +216,34 @@ public class SimpleUserData implements UserData
event.ping(); event.ping();
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);
}
} }

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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));
}
}

View File

@ -0,0 +1,7 @@
package me.totalfreedom.economy;
public interface CompletedTransaction extends Transaction
{
TransactionResult getResult();
}

View File

@ -0,0 +1,8 @@
package me.totalfreedom.economy;
public interface EconomicEntity
{
EconomicEntityData getEconomicData();
String getName();
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -0,0 +1,11 @@
package me.totalfreedom.economy;
public interface Transaction
{
EconomicEntity getSource();
EconomicEntity getDestination();
long getBalance();
}

View File

@ -0,0 +1,6 @@
package me.totalfreedom.economy;
public interface TransactionLogger
{
void logTransaction(CompletedTransaction completedTransaction);
}

View File

@ -0,0 +1,12 @@
package me.totalfreedom.economy;
import net.kyori.adventure.text.Component;
public interface TransactionResult
{
String getMessage();
boolean isSuccessful();
Component getComponent();
}

View File

@ -0,0 +1,6 @@
package me.totalfreedom.economy;
public interface Transactor
{
CompletedTransaction handleTransaction(MutableTransaction transaction);
}

View File

@ -1,10 +1,25 @@
package me.totalfreedom.user; package me.totalfreedom.user;
import me.totalfreedom.security.perm.PermissionHolder; import me.totalfreedom.security.perm.PermissionHolder;
import me.totalfreedom.economy.EconomicEntity;
import me.totalfreedom.economy.EconomicEntityData;
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();

View File

@ -1,12 +1,13 @@
package me.totalfreedom.user; package me.totalfreedom.user;
import me.totalfreedom.security.perm.Group; import me.totalfreedom.security.perm.Group;
import me.totalfreedom.economy.EconomicEntityData;
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();

View File

@ -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);
}
}
}

View File

@ -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.
}
} }

View File

@ -55,3 +55,43 @@ This proof-of-concept also uses the following libraries:
[<img src="https://img.shields.io/static/v1?label=Developer&message=Video&color=blueviolet&style=for-the-badge&logo=intellijidea">](https://github.com/VideoGameSmash12) [<img src="https://img.shields.io/static/v1?label=Developer&message=Video&color=blueviolet&style=for-the-badge&logo=intellijidea">](https://github.com/VideoGameSmash12)
<br /> <br />
[<img src="https://img.shields.io/static/v1?label=Developer&message=Allink&color=blueviolet&style=for-the-badge&logo=intellijidea">](https://github.com/allinkdev) [<img src="https://img.shields.io/static/v1?label=Developer&message=Allink&color=blueviolet&style=for-the-badge&logo=intellijidea">](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