This commit is contained in:
Paul Reilly 2023-06-09 21:11:36 -05:00
parent f459842eaf
commit bacf6e8818
58 changed files with 565 additions and 668 deletions

View File

@ -34,7 +34,7 @@ import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@Info(name = "cage", description = "Cage a player.", @Info(name = "cage", description = "Cage a player.",
usage = "/cage <player> <on|off> [material]") usage = "/cage <player> <on|off> [material]")
@Permissive(perm = "datura.cage") @Permissive(perm = "datura.cage")
public class CageCommand extends Commander public class CageCommand extends Commander
{ {
@ -68,7 +68,7 @@ public class CageCommand extends Commander
@Completion(args = {"[material]"}, index = 2) @Completion(args = {"[material]"}, index = 2)
@Subcommand(permission = "datura.cage.custom", args = {Player.class, String.class, Material.class}) @Subcommand(permission = "datura.cage.custom", args = {Player.class, String.class, Material.class})
public void cagePlayer(final CommandSender sender, final Player player, final String string, public void cagePlayer(final CommandSender sender, final Player player, final String string,
final Material material) final Material material)
{ {
switch (string.toLowerCase()) switch (string.toLowerCase())
{ {

View File

@ -11,7 +11,7 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@Info(name = "locker", description = "Lock a player, preventing them from interacting with their game client.", @Info(name = "locker", description = "Lock a player, preventing them from interacting with their game client.",
usage = "/locker <player> <on|off>", aliases = {"lock", "lockup"}) usage = "/locker <player> <on|off>", aliases = {"lock", "lockup"})
@Permissive(perm = "datura.locker") @Permissive(perm = "datura.locker")
public final class LockerCommand extends Commander public final class LockerCommand extends Commander
{ {

View File

@ -6,33 +6,33 @@ import me.totalfreedom.security.NodeType;
public class DefaultNodes public class DefaultNodes
{ {
public static final Node OP = new PermissionNodeBuilder() public static final Node OP = new PermissionNodeBuilder()
.key("freedom.master_key") .key("freedom.master_key")
.value(true) .value(true)
.type(NodeType.PERMISSION) .type(NodeType.PERMISSION)
.negated(false) .negated(false)
.wildcard(true) .wildcard(true)
.build(); .build();
public static final Node NON_OP = new PermissionNodeBuilder() public static final Node NON_OP = new PermissionNodeBuilder()
.key("freedom.default") .key("freedom.default")
.value(true) .value(true)
.type(NodeType.PERMISSION) .type(NodeType.PERMISSION)
.negated(false) .negated(false)
.wildcard(false) .wildcard(false)
.build(); .build();
public static final Node ALL = new PermissionNodeBuilder() public static final Node ALL = new PermissionNodeBuilder()
.key("*") .key("*")
.value(true) .value(true)
.type(NodeType.PERMISSION) .type(NodeType.PERMISSION)
.negated(false) .negated(false)
.wildcard(true) .wildcard(true)
.build(); .build();
public static final Node NONE = new PermissionNodeBuilder() public static final Node NONE = new PermissionNodeBuilder()
.key("freedom.none") .key("freedom.none")
.value(true) .value(true)
.type(NodeType.PERMISSION) .type(NodeType.PERMISSION)
.negated(false) .negated(false)
.wildcard(false) .wildcard(false)
.build(); .build();
private DefaultNodes() private DefaultNodes()
{ {

View File

@ -28,11 +28,11 @@ public class FreedomGroup implements Group
private final PermissionAttachment attachment; private final PermissionAttachment attachment;
public FreedomGroup(final Component name, public FreedomGroup(final Component name,
final Component prefix, final Component prefix,
final Component abbreviation, final Component abbreviation,
final int weight, final int weight,
final boolean isDefault, final boolean isDefault,
final boolean isHidden) final boolean isHidden)
{ {
this.name = name; this.name = name;
this.prefix = prefix; this.prefix = prefix;
@ -121,11 +121,11 @@ public class FreedomGroup implements Group
public boolean isPermissionSet(@NotNull final Permission perm) public boolean isPermissionSet(@NotNull final Permission perm)
{ {
final Node node = permissions() final Node node = permissions()
.stream() .stream()
.filter(n -> n.bukkit() .filter(n -> n.bukkit()
.equals(perm)) .equals(perm))
.findFirst() .findFirst()
.orElse(null); .orElse(null);
return node != null && node.value(); return node != null && node.value();
} }
@ -146,30 +146,29 @@ public class FreedomGroup implements Group
public boolean hasPermission(@NotNull final Permission perm) public boolean hasPermission(@NotNull final Permission perm)
{ {
final Node node = permissions() final Node node = permissions()
.stream() .stream()
.filter(n -> n.bukkit() .filter(n -> n.bukkit()
.equals(perm)) .equals(perm))
.findFirst() .findFirst()
.orElse(null); .orElse(null);
return node != null && node.value(); return node != null && node.value();
} }
/** /**
* Adds a permission to the relative PermissionAttachment for this group. * Adds a permission to the relative PermissionAttachment for this group. This method is not thread-safe and should
* This method is not thread-safe and should not be called asynchronously. * not be called asynchronously.
* <p> * <p>
* This method is only here for compatibility with the Bukkit API. * This method is only here for compatibility with the Bukkit API.
* *
* @param plugin The plugin responsible for this attachment. May not be null * @param plugin The plugin responsible for this attachment. May not be null or disabled.
* or disabled.
* @param name Name of the permission to attach * @param name Name of the permission to attach
* @param value Value of the permission * @param value Value of the permission
* @return This group's PermissionAttachment. * @return This group's PermissionAttachment.
*/ */
@Override @Override
public @NotNull PermissionAttachment addAttachment(@NotNull final Plugin plugin, @NotNull final String name, public @NotNull PermissionAttachment addAttachment(@NotNull final Plugin plugin, @NotNull final String name,
final boolean value) final boolean value)
{ {
attachment.setPermission(name, value); attachment.setPermission(name, value);
return attachment; return attachment;
@ -183,7 +182,7 @@ public class FreedomGroup implements Group
@Override @Override
public @Nullable PermissionAttachment addAttachment(@NotNull final Plugin plugin, @NotNull final String name, public @Nullable PermissionAttachment addAttachment(@NotNull final Plugin plugin, @NotNull final String name,
final boolean value, final int ticks) final boolean value, final int ticks)
{ {
attachment.setPermission(name, value); attachment.setPermission(name, value);
return attachment; return attachment;
@ -211,23 +210,23 @@ public class FreedomGroup implements Group
public @NotNull Set<PermissionAttachmentInfo> getEffectivePermissions() public @NotNull Set<PermissionAttachmentInfo> getEffectivePermissions()
{ {
return permissions() return permissions()
.stream() .stream()
.map(n -> new PermissionAttachmentInfo( .map(n -> new PermissionAttachmentInfo(
this, this,
n.key(), n.key(),
attachment, attachment,
n.value())) n.value()))
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }
@Override @Override
public boolean isOp() public boolean isOp()
{ {
final Node node = permissions() final Node node = permissions()
.stream() .stream()
.filter(n -> n.equals(DefaultNodes.OP)) .filter(n -> n.equals(DefaultNodes.OP))
.findFirst() .findFirst()
.orElse(null); .orElse(null);
return node != null && node.value(); return node != null && node.value();
} }

View File

@ -23,9 +23,9 @@ import java.util.Set;
import java.util.UUID; import java.util.UUID;
/** /**
* The superinterface User extends PermissionHolder, * The superinterface User extends PermissionHolder, which is an extension of
* which is an extension of {@link org.bukkit.permissions.Permissible}. * {@link org.bukkit.permissions.Permissible}. This means that our permission data can be interchanged with other
* This means that our permission data can be interchanged with other permission plugins. * permission plugins.
*/ */
public class FreedomUser implements User public class FreedomUser implements User
{ {
@ -139,7 +139,7 @@ public class FreedomUser implements User
@Override @Override
public @NotNull PermissionAttachment addAttachment(@NotNull final Plugin plugin, @NotNull final String name, public @NotNull PermissionAttachment addAttachment(@NotNull final Plugin plugin, @NotNull final String name,
final boolean value) final boolean value)
{ {
final Player player = Bukkit.getPlayer(uuid); final Player player = Bukkit.getPlayer(uuid);
if (player != null) if (player != null)
@ -164,7 +164,7 @@ public class FreedomUser implements User
@Override @Override
public @Nullable PermissionAttachment addAttachment(@NotNull final Plugin plugin, @NotNull final String name, public @Nullable PermissionAttachment addAttachment(@NotNull final Plugin plugin, @NotNull final String name,
final boolean value, final int ticks) final boolean value, final int ticks)
{ {
final Player player = Bukkit.getPlayer(uuid); final Player player = Bukkit.getPlayer(uuid);
if (player != null) if (player != null)

View File

@ -16,9 +16,9 @@ record PermissionNode(String key,
public Permission bukkit() public Permission bukkit()
{ {
return new Permission(key(), return new Permission(key(),
value() value()
? PermissionDefault.TRUE ? PermissionDefault.TRUE
: PermissionDefault.FALSE); : PermissionDefault.FALSE);
} }
@Override @Override
@ -26,8 +26,8 @@ record PermissionNode(String key,
{ {
return node.key() return node.key()
.equalsIgnoreCase(key()) .equalsIgnoreCase(key())
&& node.value() == value() && node.value() == value()
&& node.type() == type(); && node.type() == type();
} }
@Override @Override

View File

@ -51,10 +51,9 @@ public class Cager extends Service
} }
/** /**
* This method generates a cube centered around the passed location, * This method generates a cube centered around the passed location, made of the provided material. This method
* made of the provided material. This method returns the passed location object. * returns the passed location object. We use the {@link ShapeUtils} class to generate the cube, which allows us to
* We use the {@link ShapeUtils} class to generate the cube, which allows us to define * define custom shapes using {@link DoubleUnaryOperator}s.
* custom shapes using {@link DoubleUnaryOperator}s.
* *
* @param location The location to center the cube around. * @param location The location to center the cube around.
* @param material The material to use for the cube. * @param material The material to use for the cube.
@ -108,8 +107,7 @@ public class Cager extends Service
} }
/** /**
* This method will check to make sure each caged player remains within their cage. * This method will check to make sure each caged player remains within their cage. We use
* We use
* <p> * <p>
* <code>{@link Location#distanceSquared(Location)} * {@link Math#pow(double, double)}</code> * <code>{@link Location#distanceSquared(Location)} * {@link Math#pow(double, double)}</code>
* <p> * <p>

View File

@ -81,9 +81,9 @@ public class Locker extends Service
final SplittableRandom random = new SplittableRandom(); final SplittableRandom random = new SplittableRandom();
player.getEyeLocation() player.getEyeLocation()
.add(new Vector( .add(new Vector(
random.nextDouble(-1.0, 1.0), random.nextDouble(-1.0, 1.0),
random.nextDouble(-1.0, 1.0), random.nextDouble(-1.0, 1.0),
random.nextDouble(-1.0, 1.0) random.nextDouble(-1.0, 1.0)
)); ));
} }
} }

View File

@ -29,8 +29,7 @@ public class MySQL implements SQL
} }
/** /**
* Adds credentials to the MySQL URL. * Adds credentials to the MySQL URL. If the URL already contains credentials, they will be overwritten.
* If the URL already contains credentials, they will be overwritten.
* *
* @param username The username to add * @param username The username to add
* @param password The password to add * @param password The password to add
@ -61,25 +60,24 @@ public class MySQL implements SQL
public CompletableFuture<PreparedStatement> prepareStatement(final String query, final Object... args) public CompletableFuture<PreparedStatement> prepareStatement(final String query, final Object... args)
{ {
return getConnection() return getConnection()
.thenApplyAsync(connection -> .thenApplyAsync(connection ->
{ {
try try
{ {
final PreparedStatement statement = connection.prepareStatement(query); final PreparedStatement statement = connection.prepareStatement(query);
for (int i = 0; i < args.length; i++) for (int i = 0; i < args.length; i++)
{ {
statement.setObject(i + 1, args[i]); statement.setObject(i + 1, args[i]);
} }
return statement; return statement;
} } catch (SQLException ex)
catch (SQLException ex) {
{ throw new CompletionException("Failed to prepare statement: "
throw new CompletionException("Failed to prepare statement: " + query + "\n", ex);
+ query + "\n", ex); }
} }, CommonsBase.getInstance()
}, CommonsBase.getInstance() .getExecutor()
.getExecutor() .getAsync());
.getAsync());
} }
private CompletableFuture<Connection> getConnection() private CompletableFuture<Connection> getConnection()
@ -89,11 +87,10 @@ public class MySQL implements SQL
try try
{ {
return DriverManager.getConnection(url.toString()); return DriverManager.getConnection(url.toString());
} } catch (SQLException ex)
catch (SQLException ex)
{ {
throw new CompletionException("Failed to connect to the database: " throw new CompletionException("Failed to connect to the database: "
+ url.toString() + "\n", ex); + url.toString() + "\n", ex);
} }
}, CommonsBase.getInstance() }, CommonsBase.getInstance()
.getExecutor() .getExecutor()
@ -104,61 +101,58 @@ public class MySQL implements SQL
public CompletableFuture<ResultSet> executeQuery(final String query, final Object... args) public CompletableFuture<ResultSet> executeQuery(final String query, final Object... args)
{ {
return prepareStatement(query, args) return prepareStatement(query, args)
.thenApplyAsync(statement -> .thenApplyAsync(statement ->
{ {
try try
{ {
return statement.executeQuery(); return statement.executeQuery();
} } catch (SQLException ex)
catch (SQLException ex) {
{ throw new CompletionException(
throw new CompletionException( "Failed to retrieve a result set from query: "
"Failed to retrieve a result set from query: " + query + "\n", ex);
+ query + "\n", ex); }
} }, CommonsBase.getInstance()
}, CommonsBase.getInstance() .getExecutor()
.getExecutor() .getAsync());
.getAsync());
} }
@Override @Override
public CompletableFuture<Integer> executeUpdate(final String query, final Object... args) public CompletableFuture<Integer> executeUpdate(final String query, final Object... args)
{ {
return prepareStatement(query, args) return prepareStatement(query, args)
.thenApplyAsync(statement -> .thenApplyAsync(statement ->
{ {
try try
{ {
return statement.executeUpdate(); return statement.executeUpdate();
} } catch (SQLException ex)
catch (SQLException ex) {
{ throw new CompletionException("Failed to execute update: "
throw new CompletionException("Failed to execute update: " + query + "\n", ex);
+ query + "\n", ex); }
} }, CommonsBase.getInstance()
}, CommonsBase.getInstance() .getExecutor()
.getExecutor() .getAsync());
.getAsync());
} }
@Override @Override
public CompletableFuture<Boolean> execute(final String query, final Object... args) public CompletableFuture<Boolean> execute(final String query, final Object... args)
{ {
return prepareStatement(query, args) return prepareStatement(query, args)
.thenApplyAsync(statement -> .thenApplyAsync(statement ->
{ {
try try
{ {
return statement.execute(); return statement.execute();
} } catch (SQLException ex)
catch (SQLException ex) {
{ throw new CompletionException("Failed to execute statement: "
throw new CompletionException("Failed to execute statement: " + query + "\n", ex);
+ query + "\n", ex); }
} }, CommonsBase.getInstance()
}, CommonsBase.getInstance() .getExecutor()
.getExecutor() .getAsync());
.getAsync());
} }
@Override @Override
@ -181,46 +175,45 @@ public class MySQL implements SQL
} }
public <T> CompletableFuture<T> getColumn(final String table, final String column, final String key, public <T> CompletableFuture<T> getColumn(final String table, final String column, final String key,
final Identity identity, final Class<T> type) final Identity identity, final Class<T> type)
{ {
return executeQuery("SELECT ? FROM ? WHERE ? = ?", column, table, key, identity.getId()) return executeQuery("SELECT ? FROM ? WHERE ? = ?", column, table, key, identity.getId())
.thenApplyAsync(resultSet -> .thenApplyAsync(resultSet ->
{ {
try try
{ {
if (resultSet.next()) if (resultSet.next())
{ {
return resultSet.getObject(column, type); return resultSet.getObject(column, type);
} }
} } catch (SQLException ex)
catch (SQLException ex) {
{ throw new CompletionException(
throw new CompletionException( "Failed to retrieve column: " + column + " from table: " + table + " " +
"Failed to retrieve column: " + column + " from table: " + table + " " + "where primary key: " + key + " is equal to: " + identity.getId() + "\n",
"where primary key: " + key + " is equal to: " + identity.getId() + "\n", ex);
ex); }
} return null;
return null; }, CommonsBase.getInstance()
}, CommonsBase.getInstance() .getExecutor()
.getExecutor() .getAsync());
.getAsync());
} }
public CompletableFuture<Boolean> updateColumn(final String table, final String column, final Object value, public CompletableFuture<Boolean> updateColumn(final String table, final String column, final Object value,
final String key, final Identity identity) final String key, final Identity identity)
{ {
return executeUpdate("UPDATE ? SET ? = ? WHERE ? = ?", table, column, value, key, identity.getId()) return executeUpdate("UPDATE ? SET ? = ? WHERE ? = ?", table, column, value, key, identity.getId())
.thenApplyAsync(result -> result > 0, CommonsBase.getInstance() .thenApplyAsync(result -> result > 0, CommonsBase.getInstance()
.getExecutor() .getExecutor()
.getAsync()); .getAsync());
} }
public CompletableFuture<Boolean> deleteRow(final String table, final String key, final Identity identity) public CompletableFuture<Boolean> deleteRow(final String table, final String key, final Identity identity)
{ {
return executeUpdate("DELETE FROM ? WHERE ? = ?", table, key, identity.getId()) return executeUpdate("DELETE FROM ? WHERE ? = ?", table, key, identity.getId())
.thenApplyAsync(result -> result > 0, CommonsBase.getInstance() .thenApplyAsync(result -> result > 0, CommonsBase.getInstance()
.getExecutor() .getExecutor()
.getAsync()); .getAsync());
} }
public CompletableFuture<Boolean> insertRow(final String table, final Object... values) public CompletableFuture<Boolean> insertRow(final String table, final Object... values)

View File

@ -7,18 +7,16 @@ import me.totalfreedom.economy.EconomicEntityData;
* Represents the server's economy holder. * Represents the server's economy holder.
* <br> * <br>
* <br> * <br>
* This is effectively a Bank object which is meant to represent the server itself, * This is effectively a Bank object which is meant to represent the server itself, which can store a balance and
* which can store a balance and perform transactions with other EconomicEntity objects. * perform transactions with other EconomicEntity objects.
* <br> * <br>
* <br> * <br>
* The server is initially given a maximum balance of {@link Long#MAX_VALUE}, though this can be changed * The server is initially given a maximum balance of {@link Long#MAX_VALUE}, though this can be changed using the
* using the constructor {@link #ServerEconomyHolder(String, long)}. The value that this * constructor {@link #ServerEconomyHolder(String, long)}. The value that this bank object holds is persistent, which
* bank object holds is persistent, which means that the total economic resources available * means that the total economic resources available are of limited supply.
* are of limited supply.
* <br> * <br>
* <br> * <br>
* Please be aware, if the server's economy falls below 0, * Please be aware, if the server's economy falls below 0, it will have drastic consequences.
* it will have drastic consequences.
*/ */
public class ServerEconomyHolder implements EconomicEntity, EconomicEntityData public class ServerEconomyHolder implements EconomicEntity, EconomicEntityData
{ {
@ -49,9 +47,9 @@ public class ServerEconomyHolder implements EconomicEntity, EconomicEntityData
} }
/** /**
* This method will return this object, as it is both the EconomicEntity and the EconomicEntityData. * This method will return this object, as it is both the EconomicEntity and the EconomicEntityData. This is due to
* This is due to the fact that the server should only ever have one singular concrete representation * the fact that the server should only ever have one singular concrete representation of it's economic entity and
* of it's economic entity and the respective data. * the respective data.
* *
* @return this object. * @return this object.
*/ */
@ -71,8 +69,7 @@ public class ServerEconomyHolder implements EconomicEntity, EconomicEntityData
} }
/** /**
* This method will always return false, as the server should not ever be * This method will always return false, as the server should not ever be prevented from performing transactions.
* prevented from performing transactions.
* *
* @return false * @return false
*/ */
@ -103,8 +100,7 @@ public class ServerEconomyHolder implements EconomicEntity, EconomicEntityData
} }
/** /**
* Adds the specified amount to the server's balance. * Adds the specified amount to the server's balance. This method mutates the balance and returns the new balance.
* This method mutates the balance and returns the new balance.
* *
* @param amount The amount to add. * @param amount The amount to add.
* @return The new balance. * @return The new balance.
@ -117,8 +113,8 @@ public class ServerEconomyHolder implements EconomicEntity, EconomicEntityData
} }
/** /**
* Removes the specified amount from the server's balance. * Removes the specified amount from the server's balance. This method mutates the balance and returns the new
* This method mutates the balance and returns the new balance. * balance.
* *
* @param amount The amount to remove. * @param amount The amount to remove.
* @return The new balance. * @return The new balance.

View File

@ -42,14 +42,14 @@ public class SimpleUserData implements UserData
} }
private SimpleUserData( private SimpleUserData(
final UUID uuid, final UUID uuid,
final String username, final String username,
final User user, final User user,
final Group group, final Group group,
final long playtime, final long playtime,
final boolean canInteract, final boolean canInteract,
final long balance, final long balance,
final boolean transactionsFrozen) final boolean transactionsFrozen)
{ {
this.uuid = uuid; this.uuid = uuid;
this.username = username; this.username = username;
@ -66,57 +66,56 @@ public class SimpleUserData implements UserData
return sql.executeQuery("SELECT * FROM users WHERE UUID = ?", uuid) return sql.executeQuery("SELECT * FROM users WHERE UUID = ?", uuid)
.thenApplyAsync(result -> .thenApplyAsync(result ->
{ {
try try
{ {
if (result.next()) if (result.next())
{ {
final String g = result.getString("group"); final String g = result.getString("group");
final UUID u = UUID.fromString(uuid); final UUID u = UUID.fromString(uuid);
final String username = result.getString("username"); final String username = result.getString("username");
final Player player = Bukkit.getPlayer(u); final Player player = Bukkit.getPlayer(u);
if (player == null) if (player == null)
throw new IllegalStateException("Player should be online but they are not!"); throw new IllegalStateException("Player should be online but they are not!");
final User user = new FreedomUser(player); final User user = new FreedomUser(player);
final Group group = CommonsBase.getInstance() final Group group = CommonsBase.getInstance()
.getRegistrations() .getRegistrations()
.getGroupRegistry() .getGroupRegistry()
.getGroup(g); .getGroup(g);
final long playtime = result.getLong("playtime"); final long playtime = result.getLong("playtime");
final boolean canInteract = result.getBoolean("canInteract"); final boolean canInteract = result.getBoolean("canInteract");
final long balance = result.getLong("balance"); final long balance = result.getLong("balance");
final boolean transactionsFrozen = result.getBoolean("transactionsFrozen"); final boolean transactionsFrozen = result.getBoolean("transactionsFrozen");
return new SimpleUserData(u, username, user, group, playtime, return new SimpleUserData(u, username, user, group, playtime,
canInteract, balance, transactionsFrozen); canInteract, balance, transactionsFrozen);
} }
} } catch (SQLException ex)
catch (SQLException ex) {
{ final String sb = "An error occurred while trying to retrieve user data for" +
final String sb = "An error occurred while trying to retrieve user data for" + " UUID " +
" UUID " + uuid +
uuid + " from the database." +
" from the database." + "\nCaused by: " +
"\nCaused by: " + ExceptionUtils.getRootCauseMessage(ex) +
ExceptionUtils.getRootCauseMessage(ex) + "\nStack trace: " +
"\nStack trace: " + ExceptionUtils.getStackTrace(ex);
ExceptionUtils.getStackTrace(ex);
FreedomLogger.getLogger("Datura") FreedomLogger.getLogger("Datura")
.error(sb); .error(sb);
} }
final Player player = Bukkit.getPlayer(UUID.fromString(uuid)); final Player player = Bukkit.getPlayer(UUID.fromString(uuid));
if (player == null) throw new IllegalStateException("Player should be online but they are not!"); if (player == null) throw new IllegalStateException("Player should be online but they are not!");
return new SimpleUserData(player); return new SimpleUserData(player);
}, CommonsBase.getInstance() }, CommonsBase.getInstance()
.getExecutor() .getExecutor()
.getAsync()) .getAsync())
.join(); .join();
} }

View File

@ -20,6 +20,6 @@ public class Fossil extends JavaPlugin
registration.getServiceTaskRegistry() registration.getServiceTaskRegistry()
.registerService( .registerService(
SubscriptionProvider.syncService(this, trailer)); SubscriptionProvider.syncService(this, trailer));
} }
} }

View File

@ -32,17 +32,18 @@ public class PadHolder implements Listener
*/ */
public PadHolder() public PadHolder()
{ {
Bukkit.getPluginManager().registerEvents(this, CommonsBase Bukkit.getPluginManager()
.getInstance() .registerEvents(this, CommonsBase
.getRegistrations() .getInstance()
.getModuleRegistry() .getRegistrations()
.getProvider(Fossil.class) .getModuleRegistry()
.getModule()); .getProvider(Fossil.class)
.getModule());
} }
/** /**
* Adds a pad for the given player. If the player already has a pad stored in the map, * Adds a pad for the given player. If the player already has a pad stored in the map, it will be overwritten with
* it will be overwritten with the new pad. * the new pad.
* *
* @param player The player to add the pad for. * @param player The player to add the pad for.
* @param pad The pad to add. * @param pad The pad to add.
@ -63,8 +64,8 @@ public class PadHolder implements Listener
} }
/** /**
* Gets the pad for the given player, if the player has one. * Gets the pad for the given player, if the player has one. If the player has no active pad, this will return
* If the player has no active pad, this will return null. * null.
* *
* @param player The player to get the pad for. * @param player The player to get the pad for.
* @return The pad for the given player. * @return The pad for the given player.
@ -98,8 +99,8 @@ public class PadHolder implements Listener
/** /**
* Handles player pad interaction. This will check the relative block for each acceptible direction, and pass the * Handles player pad interaction. This will check the relative block for each acceptible direction, and pass the
* resulting block face (if any) to the bounce pad. See {@link BouncyPad#bouncePad(Player, org.bukkit.block.BlockFace)} * resulting block face (if any) to the bounce pad. See
* for how the resulting block face is processed. * {@link BouncyPad#bouncePad(Player, org.bukkit.block.BlockFace)} for how the resulting block face is processed.
* *
* @param event The event which gets called when a player moves. * @param event The event which gets called when a player moves.
*/ */
@ -122,10 +123,10 @@ public class PadHolder implements Listener
final Block yNeg1 = getRelative(location, 0, -1, 0); final Block yNeg1 = getRelative(location, 0, -1, 0);
Stream.of(xNeg1, xPos1, zNeg1, zPos1, yNeg1) Stream.of(xNeg1, xPos1, zNeg1, zPos1, yNeg1)
.filter(this::isWool) .filter(this::isWool)
.map(block -> block.getFace(location.getBlock())) .map(block -> block.getFace(location.getBlock()))
.findFirst() .findFirst()
.ifPresent(face -> pad.bouncePad(player, face)); .ifPresent(face -> pad.bouncePad(player, face));
} }
/** /**
@ -139,7 +140,8 @@ public class PadHolder implements Listener
*/ */
private Block getRelative(final Location location, final int x, final int y, final int z) private Block getRelative(final Location location, final int x, final int y, final int z)
{ {
return location.getBlock().getRelative(x, y, z); return location.getBlock()
.getRelative(x, y, z);
} }
/** /**

View File

@ -12,8 +12,8 @@ public enum PadType
*/ */
NORMAL, NORMAL,
/** /**
* A pad which will bounce the player on {@link BlockFace#NORTH}, {@link BlockFace#SOUTH}, {@link BlockFace#EAST} * A pad which will bounce the player on {@link BlockFace#NORTH}, {@link BlockFace#SOUTH}, {@link BlockFace#EAST} or
* or {@link BlockFace#WEST}. * {@link BlockFace#WEST}.
*/ */
SIDES, SIDES,
/** /**

View File

@ -47,8 +47,8 @@ public class CakeCommand extends Commander
public void broadcastCake(final CommandSender sender) public void broadcastCake(final CommandSender sender)
{ {
Bukkit.broadcast(FreedomMiniMessage.deserialize(true, Bukkit.broadcast(FreedomMiniMessage.deserialize(true,
"<rainbow>But there's no sense crying over every mistake. You just keep on trying till you run out of " + "<rainbow>But there's no sense crying over every mistake. You just keep on trying till you run out of " +
"cake.</rainbow>")); "cake.</rainbow>"));
final ItemStack stack = new ItemStack(Material.CAKE, 1); final ItemStack stack = new ItemStack(Material.CAKE, 1);
final ItemMeta meta = stack.getItemMeta(); final ItemMeta meta = stack.getItemMeta();

View File

@ -8,11 +8,11 @@ public class SimpleTransactionResult implements TransactionResult
{ {
public static final TransactionResult SUCCESSFUL = new SimpleTransactionResult("Successful transaction.", true); public static final TransactionResult SUCCESSFUL = new SimpleTransactionResult("Successful transaction.", true);
public static final TransactionResult UNAUTHORIZED = new SimpleTransactionResult("Unauthorized transaction.", public static final TransactionResult UNAUTHORIZED = new SimpleTransactionResult("Unauthorized transaction.",
false); false);
public static final TransactionResult AMOUNT_TOO_SMALL = new SimpleTransactionResult( public static final TransactionResult AMOUNT_TOO_SMALL = new SimpleTransactionResult(
"Transaction balance too small.", false); "Transaction balance too small.", false);
public static final TransactionResult INSUFFICIENT_FUNDS = new SimpleTransactionResult( public static final TransactionResult INSUFFICIENT_FUNDS = new SimpleTransactionResult(
"The source has an insufficient balance to carry out this transaction.", false); "The source has an insufficient balance to carry out this transaction.", false);
private final String message; private final String message;
private final Component component; private final Component component;
private final boolean successful; private final boolean successful;
@ -20,8 +20,8 @@ public class SimpleTransactionResult implements TransactionResult
public SimpleTransactionResult(final String message, final boolean successful) public SimpleTransactionResult(final String message, final boolean successful)
{ {
this(message, Component.text(message, successful this(message, Component.text(message, successful
? NamedTextColor.GREEN ? NamedTextColor.GREEN
: NamedTextColor.RED), successful); : NamedTextColor.RED), successful);
} }
public SimpleTransactionResult(final String message, final Component component, final boolean successful) public SimpleTransactionResult(final String message, final Component component, final boolean successful)

View File

@ -38,18 +38,21 @@ public final class CopyCatReaction extends Reaction
@Override @Override
public void display(final Audience audience) public void display(final Audience audience)
{ {
final BossBar bossBar = BossBarDisplay.builder().setName(getRandomCharacterString()) final BossBar bossBar = BossBarDisplay.builder()
.setProgress(0.0F) .setName(getRandomCharacterString())
.build(); .setProgress(0.0F)
.build();
} }
public String getRandomCharacterString() { public String getRandomCharacterString()
{
final SplittableRandom random = new SplittableRandom(); final SplittableRandom random = new SplittableRandom();
final StringBuilder sb = new StringBuilder(10); final StringBuilder sb = new StringBuilder(10);
final String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; final String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++)
{
sb.append(chars.charAt(random.nextInt(chars.length()))); sb.append(chars.charAt(random.nextInt(chars.length())));
} }

View File

@ -24,6 +24,6 @@ public final class FlameTrail extends SimpleTrail
final Vector direction = location.getDirection(); final Vector direction = location.getDirection();
location.getWorld() location.getWorld()
.spawnParticle(getTrailType().getType(), location, 0, direction.getX(), direction.getY(), .spawnParticle(getTrailType().getType(), location, 0, direction.getX(), direction.getY(),
direction.getZ(), 0.1); direction.getZ(), 0.1);
} }
} }

View File

@ -1,17 +1,15 @@
package me.totalfreedom.api; package me.totalfreedom.api;
/** /**
* This interface represents a Serializable object. * This interface represents a Serializable object. Objects which require custom serialization and cannot simply
* Objects which require custom serialization and cannot simply override or call * override or call the default {@link Object#toString()} method should implement this interface.
* the default {@link Object#toString()} method should implement this interface.
* *
* @param <T> The type of object to serialize * @param <T> The type of object to serialize
*/ */
public interface Serializable<T> public interface Serializable<T>
{ {
/** /**
* Serialize an object to a string. * Serialize an object to a string. Ideally, this should serialize to an SQL query for easy data transfer.
* Ideally, this should serialize to an SQL query for easy data transfer.
* *
* @param object The object to serialize * @param object The object to serialize
* @return The serialized object * @return The serialized object
@ -20,6 +18,7 @@ public interface Serializable<T>
/** /**
* Deserialize an object from a Serialized string.. * Deserialize an object from a Serialized string..
*
* @param serializedObject The serialized object * @param serializedObject The serialized object
* @return The deserialized object * @return The deserialized object
*/ */

View File

@ -25,8 +25,8 @@ public class CommonsBase extends JavaPlugin
private final FreedomExecutor executor = new FreedomExecutor(); private final FreedomExecutor executor = new FreedomExecutor();
/** /**
* Provides this plugin instance through a safe static method. * Provides this plugin instance through a safe static method. This is effectively the same thing as using
* This is effectively the same thing as using {@link JavaPlugin#getPlugin(Class)} * {@link JavaPlugin#getPlugin(Class)}
* *
* @return the plugin instance * @return the plugin instance
*/ */

View File

@ -10,9 +10,9 @@ import me.totalfreedom.data.UserRegistry;
/** /**
* This class is a holder for each registry in the data package. * This class is a holder for each registry in the data package.
* <br> * <br>
* Registries such as {@link ModuleRegistry} and {@link ServiceTaskRegistry} * Registries such as {@link ModuleRegistry} and {@link ServiceTaskRegistry} can be found as final objects in this
* can be found as final objects in this class. These registries should only ever be accessed through * class. These registries should only ever be accessed through the single Registration object in CommonsBase using
* the single Registration object in CommonsBase using {@link CommonsBase#getRegistrations()} * {@link CommonsBase#getRegistrations()}
*/ */
public class Registration public class Registration
{ {

View File

@ -25,8 +25,8 @@ import java.util.Set;
/** /**
* This class is acts as a delegate between our custom command implementation and the Bukkit API. * This class is acts as a delegate between our custom command implementation and the Bukkit API.
* <br> * <br>
* This class is not meant to be used directly, and is only public to allow for the Bukkit API to access it. * This class is not meant to be used directly, and is only public to allow for the Bukkit API to access it. As a
* As a result, this file will remain undocumented. * result, this file will remain undocumented.
* <span color=#ff0000> * <span color=#ff0000>
* <br> * <br>
* This class is not thread-safe. * This class is not thread-safe.

View File

@ -5,8 +5,8 @@ import org.bukkit.command.CommandMap;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
/** /**
* Handles the registration of commands. * Handles the registration of commands. The plugin which initializes this class should be the plugin that is
* The plugin which initializes this class should be the plugin that is registering the commands. * registering the commands.
*/ */
public class CommandHandler public class CommandHandler
{ {

View File

@ -4,8 +4,8 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
/** /**
* This annotation is used to mark a method as the command's default method. * This annotation is used to mark a method as the command's default method. This is the method that will be run to
* This is the method that will be run to execute the command when a user inputs /{command} * execute the command when a user inputs /{command}
*/ */
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface Base public @interface Base

View File

@ -11,9 +11,8 @@ import java.lang.annotation.RetentionPolicy;
public @interface Info public @interface Info
{ {
/** /**
* Technically, this is the only required value you must supply yourself. * Technically, this is the only required value you must supply yourself. However, it is HIGHLY recommended you
* However, it is HIGHLY recommended you supply the other optional values as well, * supply the other optional values as well, for better customization of your command.
* for better customization of your command.
* *
* @return The command's name. * @return The command's name.
*/ */

View File

@ -9,11 +9,10 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
/** /**
* This annotation should be used to mark methods as subcommand methods. * This annotation should be used to mark methods as subcommand methods. Subcommand methods can have custom arguments
* Subcommand methods can have custom arguments (current supported arguments can be found in the {@link ContextProvider}), * (current supported arguments can be found in the {@link ContextProvider}), and can also have a custom permission.
* and can also have a custom permission. These subcommands can also be annotated with {@link Completions} to provide * These subcommands can also be annotated with {@link Completions} to provide tab completions for the subcommand. The
* tab completions for the subcommand. The subcommand method must be public, and must be in a class that is registered * subcommand method must be public, and must be in a class that is registered with the {@link CommandHandler}.
* with the {@link CommandHandler}.
* <br> * <br>
* Tab completions with the {@link Completions} annotation are only supported for subcommands. When registering * Tab completions with the {@link Completions} annotation are only supported for subcommands. When registering
* completions, you only need to define the completion arguments a single time. If there are other methods which * completions, you only need to define the completion arguments a single time. If there are other methods which

View File

@ -17,7 +17,8 @@ public class ConfigRegistry
/** /**
* Registers a configuration. * Registers a configuration.
* @param name The name of the configuration. *
* @param name The name of the configuration.
* @param configuration The configuration. * @param configuration The configuration.
*/ */
public void register(final String name, final Configuration configuration) public void register(final String name, final Configuration configuration)
@ -27,6 +28,7 @@ public class ConfigRegistry
/** /**
* Unregisters a configuration. * Unregisters a configuration.
*
* @param name The name of the configuration. * @param name The name of the configuration.
*/ */
public void unregister(final String name) public void unregister(final String name)
@ -36,6 +38,7 @@ public class ConfigRegistry
/** /**
* Gets a configuration. * Gets a configuration.
*
* @param name The name of the configuration. * @param name The name of the configuration.
* @return The configuration. * @return The configuration.
*/ */

View File

@ -26,6 +26,7 @@ public class EventRegistry
/** /**
* Registers an event. * Registers an event.
*
* @param event The event to register. * @param event The event to register.
*/ */
public void register(final FEvent event) public void register(final FEvent event)
@ -35,6 +36,7 @@ public class EventRegistry
/** /**
* Unregisters an event. * Unregisters an event.
*
* @param event The event to unregister. * @param event The event to unregister.
*/ */
public void unregister(final FEvent event) public void unregister(final FEvent event)
@ -46,8 +48,8 @@ public class EventRegistry
* Gets an {@link EventProvider} for the specified event class which contains the actual {@link FEvent} instance. * Gets an {@link EventProvider} for the specified event class which contains the actual {@link FEvent} instance.
* *
* @param clazz The event class. * @param clazz The event class.
* @param <T> The event type.
* @return The event provider. * @return The event provider.
* @param <T> The event type.
*/ */
public <T extends FEvent> EventProvider<T> getEvent(final Class<T> clazz) public <T extends FEvent> EventProvider<T> getEvent(final Class<T> clazz)
{ {

View File

@ -26,6 +26,7 @@ public class GroupRegistry
/** /**
* Registers a group. * Registers a group.
*
* @param group The group to register. * @param group The group to register.
* @return {@code true} if the group was registered, {@code false} otherwise. * @return {@code true} if the group was registered, {@code false} otherwise.
*/ */
@ -36,6 +37,7 @@ public class GroupRegistry
/** /**
* Unregisters a group. * Unregisters a group.
*
* @param group The group to unregister. * @param group The group to unregister.
* @return {@code true} if the group was unregistered, {@code false} otherwise. * @return {@code true} if the group was unregistered, {@code false} otherwise.
*/ */
@ -46,6 +48,7 @@ public class GroupRegistry
/** /**
* Gets a group by name. * Gets a group by name.
*
* @param name The name of the group. * @param name The name of the group.
* @return The group, or {@code null} if no group was found. * @return The group, or {@code null} if no group was found.
*/ */

View File

@ -21,9 +21,8 @@ import java.util.List;
* <br> * <br>
* <br> * <br>
* <b>Tasks</b> are runnable tasks which execute at the provided times in the {@link Task} and * <b>Tasks</b> are runnable tasks which execute at the provided times in the {@link Task} and
* {@link TaskSubscription} classes. These define whether the Task is repeating, delayed, or just a one-time task. * {@link TaskSubscription} classes. These define whether the Task is repeating, delayed, or just a one-time task. Tasks
* Tasks are registered using {@link #registerTask(TaskSubscription)} and can be started using * are registered using {@link #registerTask(TaskSubscription)} and can be started using {@link #startTask(Class)}.
* {@link #startTask(Class)}.
* <br> * <br>
* <br> * <br>
* <b>ServiceSubscriptions</b> and <b>TaskSubscriptions</b> can both be easily obtained using the * <b>ServiceSubscriptions</b> and <b>TaskSubscriptions</b> can both be easily obtained using the
@ -59,16 +58,14 @@ public class ServiceTaskRegistry
/** /**
* Starts all services registered with the registry. * Starts all services registered with the registry.
* <br> * <br>
* This method should be <i>avoided</i>, due to the fact that <b><i>modules may have registered their services * This method should be <i>avoided</i>, due to the fact that <b><i>modules may have registered their services after
* after this method * this method has already been called.</i></b> In this case, it is preferred to start each service using
* has already been called.</i></b> In this case, it is preferred to start * {@link #startService(Class)}.
* each service using {@link #startService(Class)}.
* <br> * <br>
* However, <i><b>Patchwork calls this method when the server is starting up</b></i>, as Patchwork is the central * However, <i><b>Patchwork calls this method when the server is starting up</b></i>, as Patchwork is the central
* resource * resource manager for registered tasks and services. Patchwork will call this method on the first server tick, so
* manager for registered tasks and services. Patchwork will call this method on the first server tick, so unless * unless you are registering services <b>AND</b> starting them <b>POST WORLD</b>, you do not need to worry about
* you are registering services <b>AND</b> starting them <b>POST WORLD</b>, you do not need to worry about starting * starting your services.
* your services.
*/ */
public void startAllServices() public void startAllServices()
{ {
@ -82,16 +79,13 @@ public class ServiceTaskRegistry
* Starts all tasks registered with the registry. * Starts all tasks registered with the registry.
* <br> * <br>
* This method should be <i>avoided</i>, due to the fact that <b><i>modules may have registered their tasks after * This method should be <i>avoided</i>, due to the fact that <b><i>modules may have registered their tasks after
* this method * this method has already been called.</i></b> In this case, it is preferred to start each task using
* has already been called.</i></b> In this case, it is preferred to start * {@link #startTask(Class)}.
* each task
* using {@link #startTask(Class)}.
* <br> * <br>
* However, <i><b>Patchwork calls this method when the server is starting up</b></i>, as Patchwork is the central * However, <i><b>Patchwork calls this method when the server is starting up</b></i>, as Patchwork is the central
* resource * resource manager for registered tasks and services. Patchwork will call this method on the first server tick, so
* manager for registered tasks and services. Patchwork will call this method on the first server tick, so unless * unless you are registering tasks <b>AND</b> starting them <b>POST WORLD</b>, you do not need to worry about
* you are registering tasks <b>AND</b> starting them <b>POST WORLD</b>, you do not need to worry about starting * starting your tasks.
* your tasks.
*/ */
public void startAllTasks() public void startAllTasks()
{ {
@ -105,13 +99,13 @@ public class ServiceTaskRegistry
* Stops all services registered with the registry. * Stops all services registered with the registry.
* <br> * <br>
* This method should be <i>avoided</i>, due to the fact that <b><i>modules should be handling their own * This method should be <i>avoided</i>, due to the fact that <b><i>modules should be handling their own
* registrations</i></b>. * registrations</i></b>. It is preferred to use {@link #stopService(Class)} for each service you would like to
* It is preferred to use {@link #stopService(Class)} for each service you would like to stop. * stop.
* <br> * <br>
* However, <b><i>Patchwork calls this method when the server is shutting down</i></b>, or when Patchwork is being * However, <b><i>Patchwork calls this method when the server is shutting down</i></b>, or when Patchwork is being
* disabled, as Patchwork is the central resource manager for registered tasks and services. * disabled, as Patchwork is the central resource manager for registered tasks and services. Unless you are
* Unless you are <b>modifying service states while the server is running</b>, you do not need to worry about * <b>modifying service states while the server is running</b>, you do not need to worry about disabling or
* disabling or unregistering your services. * unregistering your services.
*/ */
public void stopAllServices() public void stopAllServices()
{ {
@ -125,13 +119,12 @@ public class ServiceTaskRegistry
* Stops all tasks registered with the registry. * Stops all tasks registered with the registry.
* <br> * <br>
* This method should be <i>avoided</i>, due to the fact that <b><i>modules should be handling their own * This method should be <i>avoided</i>, due to the fact that <b><i>modules should be handling their own
* registrations</i></b>. * registrations</i></b>. It is preferred to use {@link #stopTask(Class)} for each task you would like to stop.
* It is preferred to use {@link #stopTask(Class)} for each task you would like to stop.
* <br> * <br>
* However, <b><i>Patchwork calls this method when the server is shutting down</i></b>, or when Patchwork is being * However, <b><i>Patchwork calls this method when the server is shutting down</i></b>, or when Patchwork is being
* disabled, as Patchwork is the central resource manager for registered tasks and services. * disabled, as Patchwork is the central resource manager for registered tasks and services. Unless you are
* Unless you are <b>modifying task states while the server is running</b>, you do not need to worry about * <b>modifying task states while the server is running</b>, you do not need to worry about disabling or
* disabling or unregistering your tasks. * unregistering your tasks.
*/ */
public void stopAllTasks() public void stopAllTasks()
{ {

View File

@ -71,7 +71,8 @@ public class UserRegistry
/** /**
* Registers the given {@link User} and {@link UserData} objects. * Registers the given {@link User} and {@link UserData} objects.
* @param user The {@link User} to register. *
* @param user The {@link User} to register.
* @param userData The {@link UserData} to register. * @param userData The {@link UserData} to register.
*/ */
public void registerUserData(final User user, final UserData userData) public void registerUserData(final User user, final UserData userData)
@ -81,6 +82,7 @@ public class UserRegistry
/** /**
* Unregisters the given {@link User} and {@link UserData} objects. * Unregisters the given {@link User} and {@link UserData} objects.
*
* @param user The {@link User} to unregister. * @param user The {@link User} to unregister.
*/ */
public void unregisterUserData(final User user) public void unregisterUserData(final User user)
@ -90,6 +92,7 @@ public class UserRegistry
/** /**
* Gets the map of {@link User} objects to {@link UserData} objects. * Gets the map of {@link User} objects to {@link UserData} objects.
*
* @return The map of {@link User} objects to {@link UserData} objects. * @return The map of {@link User} objects to {@link UserData} objects.
*/ */
public Map<User, UserData> getUserDataMap() public Map<User, UserData> getUserDataMap()

View File

@ -275,6 +275,7 @@ public class BossBarDisplay
/** /**
* Adds a flag to the boss bar. * Adds a flag to the boss bar.
*
* @param flag The flag to add. * @param flag The flag to add.
* @return The builder. * @return The builder.
*/ */
@ -286,6 +287,7 @@ public class BossBarDisplay
/** /**
* Adds multiple flags to the boss bar. * Adds multiple flags to the boss bar.
*
* @param flags The flags to add. * @param flags The flags to add.
* @return The builder. * @return The builder.
*/ */
@ -297,6 +299,7 @@ public class BossBarDisplay
/** /**
* Removes a flag from the boss bar. * Removes a flag from the boss bar.
*
* @param flag The flag to remove. * @param flag The flag to remove.
* @return The builder. * @return The builder.
*/ */
@ -308,6 +311,7 @@ public class BossBarDisplay
/** /**
* Removes multiple flags from the boss bar. * Removes multiple flags from the boss bar.
*
* @param flags The flags to remove. * @param flags The flags to remove.
* @return The builder. * @return The builder.
*/ */
@ -319,6 +323,7 @@ public class BossBarDisplay
/** /**
* Clears all flags from the boss bar. * Clears all flags from the boss bar.
*
* @return The builder. * @return The builder.
*/ */
public BossBarBuilder clearFlags() public BossBarBuilder clearFlags()
@ -329,6 +334,7 @@ public class BossBarDisplay
/** /**
* Sets the color of the boss bar. * Sets the color of the boss bar.
*
* @param color The color of the boss bar. * @param color The color of the boss bar.
* @return The builder. * @return The builder.
*/ */
@ -340,6 +346,7 @@ public class BossBarDisplay
/** /**
* Sets the overlay of the boss bar. * Sets the overlay of the boss bar.
*
* @param overlay The overlay of the boss bar. * @param overlay The overlay of the boss bar.
* @return The builder. * @return The builder.
*/ */
@ -351,6 +358,7 @@ public class BossBarDisplay
/** /**
* Sets the progress of the boss bar. This must satisfy {@code 0 <= progress <= 100}. * Sets the progress of the boss bar. This must satisfy {@code 0 <= progress <= 100}.
*
* @param progress The progress of the boss bar. * @param progress The progress of the boss bar.
* @return The builder. * @return The builder.
*/ */
@ -362,6 +370,7 @@ public class BossBarDisplay
/** /**
* Builds the boss bar. * Builds the boss bar.
*
* @return The {@link BossBar}. * @return The {@link BossBar}.
*/ */
public BossBar build() public BossBar build()

View File

@ -3,13 +3,15 @@ package me.totalfreedom.display;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
/** /**
* Represents an action to be performed when a player clicks on an inventory slot in the respective {@link AbstractMenu}. * Represents an action to be performed when a player clicks on an inventory slot in the respective
* {@link AbstractMenu}.
*/ */
@FunctionalInterface @FunctionalInterface
public interface ClickAction public interface ClickAction
{ {
/** /**
* Called when a player clicks on an inventory slot in the respective {@link AbstractMenu}. * Called when a player clicks on an inventory slot in the respective {@link AbstractMenu}.
*
* @param player The player who clicked. * @param player The player who clicked.
*/ */
void onClick(final Player player); void onClick(final Player player);

View File

@ -20,6 +20,7 @@ public class TitleDisplay
/** /**
* Creates a new {@link TitleDisplay} with the given {@link Title}. * Creates a new {@link TitleDisplay} with the given {@link Title}.
*
* @param title The {@link Title} to display. * @param title The {@link Title} to display.
*/ */
public TitleDisplay(final Title title) public TitleDisplay(final Title title)
@ -37,6 +38,7 @@ public class TitleDisplay
/** /**
* Displays the {@link Title} to the given {@link Audience}. * Displays the {@link Title} to the given {@link Audience}.
*
* @param audience The {@link Audience} to display the {@link Title} to. * @param audience The {@link Audience} to display the {@link Title} to.
*/ */
public void displayTo(final Audience audience) public void displayTo(final Audience audience)
@ -55,6 +57,7 @@ public class TitleDisplay
/** /**
* Sets the {@link Title} to display. * Sets the {@link Title} to display.
*
* @param title The {@link Title} to display. * @param title The {@link Title} to display.
*/ */
public void setTitle(final Title title) public void setTitle(final Title title)
@ -64,6 +67,7 @@ public class TitleDisplay
/** /**
* Displays the {@link Title} to the given {@link ForwardingAudience}. * Displays the {@link Title} to the given {@link ForwardingAudience}.
*
* @param forwardingAudience The {@link ForwardingAudience} to display the {@link Title} to. * @param forwardingAudience The {@link ForwardingAudience} to display the {@link Title} to.
*/ */
public void displayForwarded(final ForwardingAudience forwardingAudience) public void displayForwarded(final ForwardingAudience forwardingAudience)
@ -99,8 +103,7 @@ public class TitleDisplay
private Duration displayDuration; private Duration displayDuration;
/** /**
* Creates a new {@link TitleBuilder} with default values. * Creates a new {@link TitleBuilder} with default values. The default values are:
* The default values are:
* <ul> * <ul>
* <li>Empty main title</li> * <li>Empty main title</li>
* <li>Empty subtitle</li> * <li>Empty subtitle</li>
@ -108,6 +111,7 @@ public class TitleDisplay
* <li>Default fade out time</li> * <li>Default fade out time</li>
* <li>Default display duration</li> * <li>Default display duration</li>
* </ul> * </ul>
*
* @see Title#DEFAULT_TIMES * @see Title#DEFAULT_TIMES
*/ */
public TitleBuilder() public TitleBuilder()
@ -121,6 +125,7 @@ public class TitleDisplay
/** /**
* Sets the main title of the {@link Title}. * Sets the main title of the {@link Title}.
*
* @param title The main title of the {@link Title}. * @param title The main title of the {@link Title}.
* @return The {@link TitleBuilder} instance. * @return The {@link TitleBuilder} instance.
*/ */
@ -132,7 +137,8 @@ public class TitleDisplay
/** /**
* Sets the main title of the {@link Title}. * Sets the main title of the {@link Title}.
* @param title The main title of the {@link Title}. *
* @param title The main title of the {@link Title}.
* @param titleColor The color of the main title. * @param titleColor The color of the main title.
* @return The {@link TitleBuilder} instance. * @return The {@link TitleBuilder} instance.
*/ */
@ -144,6 +150,7 @@ public class TitleDisplay
/** /**
* Sets the main title of the {@link Title}. * Sets the main title of the {@link Title}.
*
* @param mainTitle The main title of the {@link Title}. * @param mainTitle The main title of the {@link Title}.
* @return The {@link TitleBuilder} instance. * @return The {@link TitleBuilder} instance.
*/ */
@ -155,6 +162,7 @@ public class TitleDisplay
/** /**
* Sets the subtitle of the {@link Title}. * Sets the subtitle of the {@link Title}.
*
* @param title The subtitle of the {@link Title}. * @param title The subtitle of the {@link Title}.
* @return The {@link TitleBuilder} instance. * @return The {@link TitleBuilder} instance.
*/ */
@ -166,7 +174,8 @@ public class TitleDisplay
/** /**
* Sets the subtitle of the {@link Title}. * Sets the subtitle of the {@link Title}.
* @param title The subtitle of the {@link Title}. *
* @param title The subtitle of the {@link Title}.
* @param titleColor The color of the subtitle. * @param titleColor The color of the subtitle.
* @return The {@link TitleBuilder} instance. * @return The {@link TitleBuilder} instance.
*/ */
@ -178,6 +187,7 @@ public class TitleDisplay
/** /**
* Sets the subtitle of the {@link Title}. * Sets the subtitle of the {@link Title}.
*
* @param subTitle The subtitle of the {@link Title}. * @param subTitle The subtitle of the {@link Title}.
* @return The {@link TitleBuilder} instance. * @return The {@link TitleBuilder} instance.
*/ */
@ -189,6 +199,7 @@ public class TitleDisplay
/** /**
* Sets the fade in time of the {@link Title}. * Sets the fade in time of the {@link Title}.
*
* @param duration The fade in time of the {@link Title}. * @param duration The fade in time of the {@link Title}.
* @return The {@link TitleBuilder} instance. * @return The {@link TitleBuilder} instance.
*/ */
@ -200,6 +211,7 @@ public class TitleDisplay
/** /**
* Sets the fade out time of the {@link Title}. * Sets the fade out time of the {@link Title}.
*
* @param duration The fade out time of the {@link Title}. * @param duration The fade out time of the {@link Title}.
* @return The {@link TitleBuilder} instance. * @return The {@link TitleBuilder} instance.
*/ */
@ -211,6 +223,7 @@ public class TitleDisplay
/** /**
* Sets the display duration of the {@link Title}. * Sets the display duration of the {@link Title}.
*
* @param duration The display duration of the {@link Title}. * @param duration The display duration of the {@link Title}.
* @return The {@link TitleBuilder} instance. * @return The {@link TitleBuilder} instance.
*/ */
@ -222,14 +235,15 @@ public class TitleDisplay
/** /**
* Builds the {@link Title} with the given parameters. * Builds the {@link Title} with the given parameters.
*
* @return The built {@link Title}. * @return The built {@link Title}.
*/ */
public Title build() public Title build()
{ {
return Title.title( return Title.title(
this.mainTitle, this.mainTitle,
this.subTitle, this.subTitle,
Title.Times.times(this.fadeIn, this.displayDuration, this.fadeOut) Title.Times.times(this.fadeIn, this.displayDuration, this.fadeOut)
); );
} }
} }

View File

@ -6,7 +6,8 @@ package me.totalfreedom.economy;
public interface EconomicEntity public interface EconomicEntity
{ {
/** /**
* Gets the {@link EconomicEntityData} (which contains various common metadata about this {@link EconomicEntity}) associated with this class * Gets the {@link EconomicEntityData} (which contains various common metadata about this {@link EconomicEntity})
* associated with this class
* *
* @return the {@link EconomicEntityData} * @return the {@link EconomicEntityData}
*/ */

View File

@ -15,6 +15,12 @@ public interface EconomicEntityData
*/ */
long getBalance(); long getBalance();
/**
* Sets the balance of the associated instance
*
* @param newBalance the new balance
*/
void setBalance(final long newBalance);
/** /**
* Adds the provided amount to the associated instance's balance * Adds the provided amount to the associated instance's balance
@ -31,11 +37,4 @@ public interface EconomicEntityData
* @return the new balance * @return the new balance
*/ */
long removeFromBalance(final long amount); long removeFromBalance(final long amount);
/**
* Sets the balance of the associated instance
*
* @param newBalance the new balance
*/
void setBalance(final long newBalance);
} }

View File

@ -3,7 +3,8 @@ package me.totalfreedom.economy;
/** /**
* A transaction that can be changed. * A transaction that can be changed.
* <p> * <p>
* IMPORTANT NOTE: Please ensure that all modifications of {@link MutableTransaction} happen BEFORE it is passed to a {@link Transactor} implementation * IMPORTANT NOTE: Please ensure that all modifications of {@link MutableTransaction} happen BEFORE it is passed to a
* {@link Transactor} implementation
*/ */
public interface MutableTransaction extends Transaction public interface MutableTransaction extends Transaction
{ {

View File

@ -1,6 +1,5 @@
package me.totalfreedom.logging; package me.totalfreedom.logging;
import me.totalfreedom.sql.SQL;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Block; import org.bukkit.block.Block;
@ -120,8 +119,8 @@ public final class InteractionFormatter
final int dotIndex = trimmed.indexOf('.'); final int dotIndex = trimmed.indexOf('.');
return (dotIndex != -1) return (dotIndex != -1)
? trimmed.substring(0, dotIndex) ? trimmed.substring(0, dotIndex)
: trimmed; : trimmed;
} }
// Format: <item>,<amount> // Format: <item>,<amount>

View File

@ -0,0 +1,50 @@
package me.totalfreedom.particle;
import org.bukkit.Particle;
import org.bukkit.World;
/**
* A utility class for the 24 different note colors available in Minecraft. Each note is represented as a double value
* between 0 and 1. Furthermore, each note is a multiple of 1/24 within that range of 0 to 1.
* <p>
* For example, the note G is represented as 1/24, or 0.042. The note C is represented as 6/24, or 0.25.
* <p>
* When spawning particles, the count must be set to 0 and the extra value set between 0 and 1. The extra value is the
* size of the note particle. To add a color, use one of the provided methods in this class for the xOffset value in
* {@link World#spawnParticle(Particle, double, double, double, int, double, double, double, double)}. The xOffset value
* is the note color, with the yOffset and zOffset values set to 0.
*/
public final class NoteColorUtil
{
public static final double CYAN_NOTE_F_SHARP_LOW = 0;
public static final double CYAN_NOTE_G = 0.042;
public static final double GRAY_NOTE_G_SHARP = 0.083;
public static final double GRAY_NOTE_A = 0.125;
public static final double GRAY_NOTE_A_SHARP = 0.167;
public static final double MAGENTA_NOTE_B = 0.208;
public static final double RED_NOTE_C = 0.25;
public static final double YELLOW_NOTE_C_SHARP = 0.292;
public static final double YELLOW_NOTE_D = 0.333;
public static final double YELLOW_NOTE_D_SHARP_LOW = 0.375;
public static final double GRAY_NOTE_E = 0.417;
public static final double GRAY_NOTE_F = 0.458;
public static final double GRAY_NOTE_F_SHARP = 0.5;
public static final double LIGHT_BLUE_NOTE_G = 0.542;
public static final double BLUE_NOTE_G_SHARP = 0.583;
public static final double PURPLE_NOTE_A = 0.625;
public static final double PURPLE_NOTE_A_SHARP = 0.667;
public static final double PURPLE_NOTE_B = 0.708;
public static final double GRAY_NOTE_C = 0.75;
public static final double GRAY_NOTE_C_SHARP = 0.792;
public static final double GRAY_NOTE_D = 0.833;
public static final double YELLOW_NOTE_D_SHARP_HIGH = 0.875;
public static final double YELLOW_NOTE_E = 0.917;
public static final double YELLOW_NOTE_F = 0.958;
public static final double CYAN_NOTE_F_SHARP_HIGH = 1;
public static final double BLACK_NOTE_NA = 32768;
private NoteColorUtil()
{
throw new AssertionError();
}
}

View File

@ -1,157 +0,0 @@
package me.totalfreedom.particle;
import org.bukkit.Particle;
import org.bukkit.World;
import java.math.RoundingMode;
import java.text.DecimalFormat;
/**
* A utility class for the 24 different note colors available in Minecraft. Each note is represented as a double value
* between 0 and 1. Furthermore, each note is a multiple of 1/24 within that range of 0 to 1.
* <p>
* For example, the note G is represented as 1/24, or 0.042. The note C is represented as 6/24, or 0.25.
* <p>
* When spawning particles, the count must be set to 0 and the extra value set between 0 and 1. The extra value is the
* size of the note particle. To add a color, use one of the provided methods in this class for the xOffset value in
* {@link World#spawnParticle(Particle, double, double, double, int, double, double, double, double)}. The xOffset value
* is the note color, with the yOffset and zOffset values set to 0.
*/
public final class NoteWrapper
{
public static final double CYAN_NOTE_F_SHARP_LOW = 0;
public static final double CYAN_NOTE_F_SHARP_HIGH = 1;
private static final DecimalFormat FORMAT;
static
{
FORMAT = new DecimalFormat("#.###");
FORMAT.setRoundingMode(RoundingMode.HALF_UP);
}
private NoteWrapper()
{
throw new AssertionError();
}
private static double round(final double value)
{
return Double.parseDouble(FORMAT.format(value));
}
public static double cyanNoteG()
{
return round(1 / 24D);
}
public static double grayNoteGSharp()
{
return round(2 / 24D);
}
public static double grayNoteA()
{
return round(3 / 24D);
}
public static double grayNoteASharp()
{
return round(4 / 24D);
}
public static double magentaNoteB()
{
return round(5 / 24D);
}
public static double redNoteC()
{
return round(6 / 24D);
}
public static double yellowNoteCSharp()
{
return round(7 / 24D);
}
public static double yellowNoteD()
{
return round(8 / 24D);
}
public static double yellowNoteDSharpLow()
{
return round(9 / 24D);
}
public static double grayNoteE()
{
return round(10 / 24D);
}
public static double grayNoteF()
{
return round(11 / 24D);
}
public static double grayNoteFSharp()
{
return round(12 / 24D);
}
public static double lightBlueNoteG()
{
return round(13 / 24D);
}
public static double blueNoteGSharp()
{
return round(14 / 24D);
}
public static double purpleNoteA()
{
return round(15 / 24D);
}
public static double purpleNoteASharp()
{
return round(16 / 24D);
}
public static double purpleNoteB()
{
return round(17 / 24D);
}
public static double grayNoteC()
{
return round(18 / 24D);
}
public static double grayNoteCSharp()
{
return round(19 / 24D);
}
public static double grayNoteD()
{
return round(20 / 24D);
}
public static double yellowNoteDSharpHigh()
{
return round(21 / 24D);
}
public static double greenNoteE()
{
return round(22 / 24D);
}
public static double lightBlueNoteF()
{
return round(23 / 24D);
}
}

View File

@ -17,9 +17,8 @@ import java.util.UUID;
public interface Trail public interface Trail
{ {
/** /**
* Returns the UUID of the player associated with the trail. This is for usage with our persistant storage * Returns the UUID of the player associated with the trail. This is for usage with our persistant storage container
* container so that we can safely send and retrieve the trails without having to directly reference a player * so that we can safely send and retrieve the trails without having to directly reference a player object.
* object.
* <br> * <br>
* TL;DR Memory optimization! * TL;DR Memory optimization!
* *
@ -30,9 +29,9 @@ public interface Trail
/** /**
* Returns the player associated with this trail. Trails are user specific, and should be persistent across all * Returns the player associated with this trail. Trails are user specific, and should be persistent across all
* usages. This is also used when displaying the particles, as they will be relative to the player's back, which * usages. This is also used when displaying the particles, as they will be relative to the player's back, which is
* is an inverse offset of the player's eye location. We use OfflinePlayer as we can make a simple check and cast * an inverse offset of the player's eye location. We use OfflinePlayer as we can make a simple check and cast to
* to determine if the player is online when spawning trails. * determine if the player is online when spawning trails.
* *
* @return The player associated with this Trail. * @return The player associated with this Trail.
*/ */
@ -50,8 +49,8 @@ public interface Trail
TrailType getTrailType(); TrailType getTrailType();
/** /**
* This method is nullable because if the value of {@link #isGradient()} is true, then * This method is nullable because if the value of {@link #isGradient()} is true, then {@link #getColors()} should
* {@link #getColors()} should be used instead, as that will contain the color data for our trail. * be used instead, as that will contain the color data for our trail.
* <br> * <br>
* However, this method will also be null if the particle type is not colorable. * However, this method will also be null if the particle type is not colorable.
* *
@ -71,8 +70,8 @@ public interface Trail
void setColor(@NotNull Color color); void setColor(@NotNull Color color);
/** /**
* This method is nullable because if the value of {@link #isGradient()} is false, then * This method is nullable because if the value of {@link #isGradient()} is false, then {@link #getColor()} should
* {@link #getColor()} should be used instead, as our trail is a single static color. * be used instead, as our trail is a single static color.
* <br> * <br>
* However, this method will also be null if the particle type is not colorable. * However, this method will also be null if the particle type is not colorable.
* *

View File

@ -1,6 +1,5 @@
package me.totalfreedom.particle; package me.totalfreedom.particle;
import org.bukkit.Note;
import org.bukkit.Particle; import org.bukkit.Particle;
public enum TrailType public enum TrailType

View File

@ -18,16 +18,16 @@ public class ContextProvider
public <T> T fromString(final String string, final Class<T> clazz) public <T> T fromString(final String string, final Class<T> clazz)
{ {
return Stream.of(toBoolean(string), return Stream.of(toBoolean(string),
toDouble(string), toDouble(string),
toInt(string), toInt(string),
toLong(string), toLong(string),
toFloat(string), toFloat(string),
toMaterial(string), toMaterial(string),
toPlayer(string), toPlayer(string),
toWorld(string), toWorld(string),
toLocation(string), toLocation(string),
toCommandSender(string), toCommandSender(string),
toComponent(string)) toComponent(string))
.filter(Objects::nonNull) .filter(Objects::nonNull)
.findFirst() .findFirst()
.map(clazz::cast) .map(clazz::cast)
@ -36,14 +36,12 @@ public class ContextProvider
private @Nullable Boolean toBoolean(final String string) private @Nullable Boolean toBoolean(final String string)
{ {
try // Previoulsy we used Boolean#parseBoolean, but that will always return a value and does not throw
{ // an exception. This means that if the string is not "true" or "false", it will return false.
return Boolean.parseBoolean(string); if (string.equalsIgnoreCase("true")) return true;
} if (string.equalsIgnoreCase("false")) return false;
catch (Exception ignored)
{ return null;
return null;
}
} }
private @Nullable Double toDouble(final String string) private @Nullable Double toDouble(final String string)
@ -51,8 +49,7 @@ public class ContextProvider
try try
{ {
return Double.parseDouble(string); return Double.parseDouble(string);
} } catch (NumberFormatException ignored)
catch (Exception ignored)
{ {
return null; return null;
} }
@ -63,8 +60,7 @@ public class ContextProvider
try try
{ {
return Integer.parseInt(string); return Integer.parseInt(string);
} } catch (NumberFormatException ignored)
catch (Exception ignored)
{ {
return null; return null;
} }
@ -75,8 +71,7 @@ public class ContextProvider
try try
{ {
return Long.parseLong(string); return Long.parseLong(string);
} } catch (NumberFormatException ignored)
catch (Exception ignored)
{ {
return null; return null;
} }
@ -87,8 +82,7 @@ public class ContextProvider
try try
{ {
return Float.parseFloat(string); return Float.parseFloat(string);
} } catch (NumberFormatException ignored)
catch (Exception ignored)
{ {
return null; return null;
} }

View File

@ -119,8 +119,8 @@ public class FreedomExecutor
} }
/** /**
* Gets the synchronous executor instance. This is a convenience for {@link CompletableFuture} invocations, * Gets the synchronous executor instance. This is a convenience for {@link CompletableFuture} invocations, when
* when defining a custom executor for the {@link CompletableFuture}. * defining a custom executor for the {@link CompletableFuture}.
* *
* @return The synchronous executor instance. * @return The synchronous executor instance.
*/ */
@ -130,8 +130,8 @@ public class FreedomExecutor
} }
/** /**
* Gets the asynchronous executor instance. This is a convenience for {@link CompletableFuture} invocations, * Gets the asynchronous executor instance. This is a convenience for {@link CompletableFuture} invocations, when
* when defining a custom executor for the {@link CompletableFuture}. * defining a custom executor for the {@link CompletableFuture}.
* *
* @return The asynchronous executor instance. * @return The asynchronous executor instance.
*/ */

View File

@ -52,10 +52,10 @@ public abstract class Task extends BukkitRunnable
} }
/** /**
* Creates a new task with the given name and delay. This will intialize a single execute task with an * Creates a new task with the given name and delay. This will intialize a single execute task with an initial delay
* initial delay before execution. * before execution.
* *
* @param name The name of the task. * @param name The name of the task.
* @param delay How long the task should wait before executing. * @param delay How long the task should wait before executing.
*/ */
protected Task(final String name, final long delay) protected Task(final String name, final long delay)
@ -64,44 +64,44 @@ public abstract class Task extends BukkitRunnable
} }
/** /**
* Creates a new task with the given name and delay. * Creates a new task with the given name and delay. This is the same as longs, except that here, we naturally
* This is the same as longs, except that here, we naturally support durations which are automatically converted to * support durations which are automatically converted to ticks for you. This means that using
* ticks for you. This means that using {@link Duration#ofSeconds(long)} will work as expected. * {@link Duration#ofSeconds(long)} will work as expected.
* *
* @param name The name of the task. * @param name The name of the task.
* @param delay How long the task should wait before executing. * @param delay How long the task should wait before executing.
*/ */
protected Task(final String name, final Duration delay) protected Task(final String name, final Duration delay)
{ {
this(name, DurationTools.getTickedSeconds(delay), -1L); this(name, DurationTools.getTicks(delay), -1L);
} }
/** /**
* Creates a new task with the given name, delay, and interval. * Creates a new task with the given name, delay, and interval. This is the same as longs, except that here, we
* This is the same as longs, except that here, we naturally support durations which are automatically converted to * naturally support durations which are automatically converted to ticks for you. This means that using
* ticks for you. This means that using {@link Duration#ofSeconds(long)} will work as expected. * {@link Duration#ofSeconds(long)} will work as expected.
* *
* @param name The name of the task. * @param name The name of the task.
* @param delay How long the task should wait before executing. * @param delay How long the task should wait before executing.
* @param interval How long the task should wait between executions. * @param interval How long the task should wait between executions.
*/ */
protected Task(final String name, final Duration delay, final Duration interval) protected Task(final String name, final Duration delay, final Duration interval)
{ {
this(name, DurationTools.getTickedSeconds(delay), DurationTools.getTickedSeconds(interval)); this(name, DurationTools.getTicks(delay), DurationTools.getTicks(interval));
} }
/** /**
* Creates a new task with the given name, delay, and interval. * Creates a new task with the given name, delay, and interval. This method is a convenience method to use a
* This method is a convenience method to use a {@link Duration} for the interval, while also being able to * {@link Duration} for the interval, while also being able to specify the delay as -1L so the task does not have an
* specify the delay as -1L so the task does not have an initial delay before execution. * initial delay before execution.
* *
* @param name The name of the task. * @param name The name of the task.
* @param delay The delay of the task. * @param delay The delay of the task.
* @param interval The interval of the task. * @param interval The interval of the task.
*/ */
protected Task(final String name, final long delay, final Duration interval) protected Task(final String name, final long delay, final Duration interval)
{ {
this(name, delay, DurationTools.getTickedSeconds(interval)); this(name, delay, DurationTools.getTicks(interval));
} }
/** /**

View File

@ -9,10 +9,10 @@ import org.bukkit.scheduler.BukkitTask;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
/** /**
* Represents a subscription to a task. Task subscriptions offer a nice wrapper for managing tasks, which are * Represents a subscription to a task. Task subscriptions offer a nice wrapper for managing tasks, which are inevitably
* inevitably just bukkit runnables with a bit more lenience in terms of instantiation modification and execution. * just bukkit runnables with a bit more lenience in terms of instantiation modification and execution. It also offers a
* It also offers a more intuitive way to manage our tasks; rather than having to keep track of task ids for each * more intuitive way to manage our tasks; rather than having to keep track of task ids for each {@link BukkitTask}
* {@link BukkitTask} object that gets returned by the {@link BukkitScheduler}. * object that gets returned by the {@link BukkitScheduler}.
* *
* @param <T> The type of task. * @param <T> The type of task.
*/ */

View File

@ -10,25 +10,29 @@ import net.kyori.adventure.bossbar.BossBar;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
public class ReactionTask extends Task implements Listener { public class ReactionTask extends Task implements Listener
{
private final Reaction reaction; private final Reaction reaction;
private final BossBarDisplay bossBarDisplay; private final BossBarDisplay bossBarDisplay;
public ReactionTask(final String name, final Reaction reaction) { public ReactionTask(final String name, final Reaction reaction)
{
super(name, -1L, -1); super(name, -1L, -1);
this.reaction = reaction; this.reaction = reaction;
final BossBar bossBar = BossBarDisplay.builder() final BossBar bossBar = BossBarDisplay.builder()
.setName(reaction.getReactionMessage()) .setName(reaction.getReactionMessage())
.setColor(BossBar.Color.GREEN) .setColor(BossBar.Color.GREEN)
.setProgress(0.0F) .setProgress(0.0F)
.build(); .build();
this.bossBarDisplay = new BossBarDisplay(bossBar); this.bossBarDisplay = new BossBarDisplay(bossBar);
} }
@Override @Override
public void run() { public void run()
if (isCancelled()) { {
if (isCancelled())
{
} }
final BossBarTimer timer = new BossBarTimer(bossBarDisplay, reaction.getReactionDuration()); final BossBarTimer timer = new BossBarTimer(bossBarDisplay, reaction.getReactionDuration());
@ -36,13 +40,15 @@ public class ReactionTask extends Task implements Listener {
} }
@EventHandler @EventHandler
public void onPlayerChat(final AsyncChatEvent event) { public void onPlayerChat(final AsyncChatEvent event)
{
if (event.message() if (event.message()
.equals(reaction.getReactionMessage())) { .equals(reaction.getReactionMessage()))
{
final EconomicEntity entity = CommonsBase.getInstance() final EconomicEntity entity = CommonsBase.getInstance()
.getRegistrations() .getRegistrations()
.getUserRegistry() .getUserRegistry()
.getUser(event.getPlayer()); .getUser(event.getPlayer());
reaction.onReact(entity); reaction.onReact(entity);
} }

View File

@ -22,10 +22,10 @@ public interface SQLProperties
default String toURLPlain() default String toURLPlain()
{ {
return String.format("jdbc:%s://%s:%s/%s", return String.format("jdbc:%s://%s:%s/%s",
this.getDriver(), this.getDriver(),
this.getHost(), this.getHost(),
this.getPort(), this.getPort(),
this.getDatabase()); this.getDatabase());
} }
String getDriver(); String getDriver();
@ -39,12 +39,12 @@ public interface SQLProperties
default String toURLWithLogin() default String toURLWithLogin()
{ {
return String.format("jdbc:%s://%s:%s/%s?user=%s&password=%s", return String.format("jdbc:%s://%s:%s/%s?user=%s&password=%s",
this.getDriver(), this.getDriver(),
this.getHost(), this.getHost(),
this.getPort(), this.getPort(),
this.getDatabase(), this.getDatabase(),
this.getUsername(), this.getUsername(),
this.getPassword()); this.getPassword());
} }
String getUsername(); String getUsername();

View File

@ -16,7 +16,7 @@ public final class DurationTools
throw new AssertionError(); throw new AssertionError();
} }
public static final long getTickedSeconds(final Duration duration) public static final long getTicks(final Duration duration)
{ {
return duration.toMillis() / 50L; return duration.toMillis() / 50L;
} }

View File

@ -34,7 +34,7 @@ public final class InterpolationUtils
} }
private static Set<Color> hsvGradient(final int length, final Color from, final Color to, private static Set<Color> hsvGradient(final int length, final Color from, final Color to,
final Interpolator interpolator) final Interpolator interpolator)
{ {
// returns a float-array where hsv[0] = hue, hsv[1] = saturation, hsv[2] = value/brightness // returns a float-array where hsv[0] = hue, hsv[1] = saturation, hsv[2] = value/brightness
final float[] hsvFrom = java.awt.Color.RGBtoHSB(from.getRed(), from.getGreen(), from.getBlue(), null); final float[] hsvFrom = java.awt.Color.RGBtoHSB(from.getRed(), from.getGreen(), from.getBlue(), null);
@ -69,18 +69,18 @@ public final class InterpolationUtils
{ {
final LinkedHashSet<TextColor> base = new LinkedHashSet<>(); final LinkedHashSet<TextColor> base = new LinkedHashSet<>();
final Set<TextColor> redToOrange = componentRGBGradient(length, NamedTextColor.RED, final Set<TextColor> redToOrange = componentRGBGradient(length, NamedTextColor.RED,
NamedTextColor.GOLD, InterpolationUtils::linear); NamedTextColor.GOLD, InterpolationUtils::linear);
final Set<TextColor> orangeToYellow = componentRGBGradient(length, NamedTextColor.GOLD, final Set<TextColor> orangeToYellow = componentRGBGradient(length, NamedTextColor.GOLD,
NamedTextColor.YELLOW, InterpolationUtils::linear); NamedTextColor.YELLOW, InterpolationUtils::linear);
final Set<TextColor> yellowToGreen = componentRGBGradient(length, NamedTextColor.YELLOW, final Set<TextColor> yellowToGreen = componentRGBGradient(length, NamedTextColor.YELLOW,
NamedTextColor.GREEN, InterpolationUtils::linear); NamedTextColor.GREEN, InterpolationUtils::linear);
final Set<TextColor> greenToBlue = componentRGBGradient(length, NamedTextColor.GREEN, final Set<TextColor> greenToBlue = componentRGBGradient(length, NamedTextColor.GREEN,
NamedTextColor.BLUE, InterpolationUtils::linear); NamedTextColor.BLUE, InterpolationUtils::linear);
final Set<TextColor> blueToPurple = componentRGBGradient(length, NamedTextColor.BLUE, final Set<TextColor> blueToPurple = componentRGBGradient(length, NamedTextColor.BLUE,
NamedTextColor.LIGHT_PURPLE, NamedTextColor.LIGHT_PURPLE,
InterpolationUtils::linear); InterpolationUtils::linear);
final Set<TextColor> purpleToRed = componentRGBGradient(length, TextColor.color(75, 0, 130), final Set<TextColor> purpleToRed = componentRGBGradient(length, TextColor.color(75, 0, 130),
TextColor.color(255, 0, 0), InterpolationUtils::linear); TextColor.color(255, 0, 0), InterpolationUtils::linear);
base.addAll(redToOrange); base.addAll(redToOrange);
base.addAll(orangeToYellow); base.addAll(orangeToYellow);
base.addAll(yellowToGreen); base.addAll(yellowToGreen);
@ -91,7 +91,7 @@ public final class InterpolationUtils
} }
private static Set<TextColor> componentRGBGradient(final int length, final TextColor from, final TextColor to, private static Set<TextColor> componentRGBGradient(final int length, final TextColor from, final TextColor to,
final Interpolator interpolator) final Interpolator interpolator)
{ {
final double[] r = interpolator.interpolate(from.red(), to.red(), length); final double[] r = interpolator.interpolate(from.red(), to.red(), length);
final double[] g = interpolator.interpolate(from.green(), to.green(), length); final double[] g = interpolator.interpolate(from.green(), to.green(), length);
@ -113,7 +113,7 @@ public final class InterpolationUtils
} }
private static Set<Color> rgbGradient(final int length, final Color from, final Color to, private static Set<Color> rgbGradient(final int length, final Color from, final Color to,
final Interpolator interpolator) final Interpolator interpolator)
{ {
final double[] r = interpolator.interpolate(from.getRed(), to.getRed(), length); final double[] r = interpolator.interpolate(from.getRed(), to.getRed(), length);
final double[] g = interpolator.interpolate(from.getGreen(), to.getGreen(), length); final double[] g = interpolator.interpolate(from.getGreen(), to.getGreen(), length);

View File

@ -21,7 +21,7 @@ public class ShapeUtils
} }
public List<Location> generate(final int count, final DoubleUnaryOperator x, final DoubleUnaryOperator y, public List<Location> generate(final int count, final DoubleUnaryOperator x, final DoubleUnaryOperator y,
final DoubleUnaryOperator z) final DoubleUnaryOperator z)
{ {
final double step = (start - end) / (count - 1); final double step = (start - end) / (count - 1);
final LinkedList<Location> lset = new LinkedList<>(); final LinkedList<Location> lset = new LinkedList<>();

View File

@ -1,12 +1,12 @@
package me.totalfreedom.utils.container; package me.totalfreedom.utils.container;
public final class Tuple<A, B, C> public final class Trio<A, B, C>
{ {
private final A a; private final A a;
private final B b; private final B b;
private final C c; private final C c;
public Tuple(final A a, final B b, final C c) public Trio(final A a, final B b, final C c)
{ {
this.a = a; this.a = a;
this.b = b; this.b = b;

View File

@ -1,12 +1,12 @@
package me.totalfreedom.utils.container; package me.totalfreedom.utils.container;
public class UnaryTuple<T> public class UnaryTrio<T>
{ {
private final T primary; private final T primary;
private final T secondary; private final T secondary;
private final T tertiary; private final T tertiary;
public UnaryTuple(final T primary, final T secondary, final T tertiary) public UnaryTrio(final T primary, final T secondary, final T tertiary)
{ {
this.primary = primary; this.primary = primary;
this.secondary = secondary; this.secondary = secondary;

View File

@ -12,7 +12,7 @@ import java.util.function.Supplier;
public class FreedomAdventure public class FreedomAdventure
{ {
private static final PlainTextComponentSerializer PLAIN_TEXT_COMPONENT_SERIALIZER = private static final PlainTextComponentSerializer PLAIN_TEXT_COMPONENT_SERIALIZER =
PlainTextComponentSerializer.plainText(); PlainTextComponentSerializer.plainText();
private FreedomAdventure() private FreedomAdventure()
{ {

View File

@ -35,14 +35,14 @@ public class FreedomMiniMessage
private static final MiniMessage unsafe = MiniMessage.miniMessage(); private static final MiniMessage unsafe = MiniMessage.miniMessage();
private static final MiniMessage safe = MiniMessage.builder() private static final MiniMessage safe = MiniMessage.builder()
.tags(TagResolver.resolver( .tags(TagResolver.resolver(
StandardTags.color(), StandardTags.color(),
StandardTags.rainbow(), StandardTags.rainbow(),
StandardTags.gradient(), StandardTags.gradient(),
StandardTags.newline(), StandardTags.newline(),
StandardTags.decorations(TextDecoration.ITALIC), StandardTags.decorations(TextDecoration.ITALIC),
StandardTags.decorations(TextDecoration.BOLD), StandardTags.decorations(TextDecoration.BOLD),
StandardTags.decorations(TextDecoration.STRIKETHROUGH), StandardTags.decorations(TextDecoration.STRIKETHROUGH),
StandardTags.decorations(TextDecoration.UNDERLINED) StandardTags.decorations(TextDecoration.UNDERLINED)
)) ))
.build(); .build();
@ -52,9 +52,8 @@ public class FreedomMiniMessage
} }
/** /**
* Deserializes an input string using an instance of MiniMessage that is either safe (resolves only a specific * Deserializes an input string using an instance of MiniMessage that is either safe (resolves only a specific set
* set of tags) * of tags) or unsafe (resolves all tags).
* or unsafe (resolves all tags).
* *
* @param safe Whether to use a safe instance of MiniMessage * @param safe Whether to use a safe instance of MiniMessage
* @param input An input string formatted with MiniMessage's input * @param input An input string formatted with MiniMessage's input

View File

@ -9,12 +9,11 @@ import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
/** /**
* This class contains different methods to provide {@link ChatType.Bound} instances for sending messages to players * This class contains different methods to provide {@link ChatType.Bound} instances for sending messages to players in
* in game. * game. This is now a requirement for all message requests to players due to the new chat signature system.
* This is now a requirement for all message requests to players due to the new chat signature system.
* <br> * <br>
* Even though Scissors has this feature disabled, upstream (Paper) and Kyori Adventure * Even though Scissors has this feature disabled, upstream (Paper) and Kyori Adventure have made the appropriate API
* have made the appropriate API changes to accomodate chat signatures. * changes to accomodate chat signatures.
* <br> * <br>
* As a result, we need to conform to those specifications even if we do not use this feature. * As a result, we need to conform to those specifications even if we do not use this feature.
*/ */
@ -34,8 +33,8 @@ public final class KyoriConstants
/** /**
* Represents a Chat Bound for a plugin. * Represents a Chat Bound for a plugin.
* <br> * <br>
* This is a convenience method so you are not required to dependency inject * This is a convenience method so you are not required to dependency inject your plugin instance any time that you
* your plugin instance any time that you need a Bound. * need a Bound.
* *
* @param pluginClass The plugin class to get the plugin instance from. * @param pluginClass The plugin class to get the plugin instance from.
* @return A ChatType.Bound instance for the plugin. * @return A ChatType.Bound instance for the plugin.
@ -55,11 +54,10 @@ public final class KyoriConstants
} }
/** /**
* Represents a Chat Bound for a player. * Represents a Chat Bound for a player. Chat bounds are required for sending messages to players.
* Chat bounds are required for sending messages to players.
* <br> * <br>
* The chat bound is a representation of a validated chat signature, * The chat bound is a representation of a validated chat signature, which is tied directly to the user's account
* which is tied directly to the user's account name. In our case, this is the player's name. * name. In our case, this is the player's name.
* *
* @param player The player to get the bound for. * @param player The player to get the bound for.
* @return A ChatType.Bound instance for the player. * @return A ChatType.Bound instance for the player.
@ -72,8 +70,8 @@ public final class KyoriConstants
/** /**
* Represents a Chat Bound for the console. * Represents a Chat Bound for the console.
* <br> * <br>
* The chat bound is a representation of a validated chat signature, * The chat bound is a representation of a validated chat signature, which is tied directly to the user's account
* which is tied directly to the user's account name. In our case, this is the player's name. * name. In our case, this is the player's name.
* *
* @param sender The console to get the bound for. * @param sender The console to get the bound for.
* @return A ChatType.Bound instance for the console. * @return A ChatType.Bound instance for the console.

View File

@ -33,8 +33,7 @@ public class FreedomLogger implements Audience
} }
/** /**
* 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
* message a player. * message a player.
* *
* @param message The message to send. * @param message The message to send.
@ -47,8 +46,7 @@ public class FreedomLogger implements Audience
} }
/** /**
* This method allows you to log a component to the console, * This method allows you to log a component to the console, while also returning a String representation of the
* while also returning a String representation of the
* component * component
* *
* @param component The component to send. * @param component The component to send.
@ -71,7 +69,9 @@ public class FreedomLogger implements Audience
logger.info(plainText); logger.info(plainText);
return 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.
* *
* @param message The message to send. * @param message The message to send.
@ -104,9 +104,8 @@ public class FreedomLogger implements Audience
} }
/** /**
* 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
* It is highly recommended to deconstruct the stack trace and pass it * pass it in a more readable format to this method.
* in a more readable format to this method.
* *
* @param message The message to send. * @param message The message to send.
*/ */
@ -126,11 +125,9 @@ public class FreedomLogger implements Audience
} }
/** /**
* This method allows you to log an error message to the console, * This method allows you to log an error message to the console, while also returning a Component that could be
* while also returning a Component that could be used to * used to message a player. It is highly recommended that you deconstruct and limit the stack trace before passing
* message a player. It is highly recommended that you deconstruct and limit * it to this method, if you are intending to use it for player communication.
* the stack trace before passing it to this method, if you are intending to
* use it for player communication.
* *
* @param message The message to send. * @param message The message to send.
* @return A component representation of the message. * @return A component representation of the message.
@ -142,9 +139,8 @@ public class FreedomLogger implements Audience
} }
/** /**
* This method allows you to log an error component to the console, * This method allows you to log an error component to the console, while also returning a String representation of
* while also returning a String representation of the error * the error component.
* component.
* *
* @param component The component to send. * @param component The component to send.
* @return A String representation of the component. * @return A String representation of the component.
@ -169,10 +165,9 @@ public class FreedomLogger implements Audience
} }
/** /**
* 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
* while also returning a Component that could be used to * to message a player. This method will only log if debug mode is enabled. If debug mode is not enabled, this
* message a player. This method will only log if debug mode is enabled. * method will return an empty component.
* If debug mode is not enabled, this method will return an empty component.
* *
* @param message The message to send. * @param message The message to send.
* @return A component representation of the message. * @return A component representation of the message.
@ -188,8 +183,8 @@ public class FreedomLogger implements Audience
} }
/** /**
* This method allows you to log a debug component to the console, * This method allows you to log a debug component to the console, while also returning a String representation of
* while also returning a String representation of the debug component. * the debug component.
* *
* @param component The component to send. * @param component The component to send.
* @return A String representation of the message. * @return A String representation of the message.
@ -204,8 +199,8 @@ public class FreedomLogger implements Audience
} }
/** /**
* This method allows you to log a debug component to the console. * This method allows you to log a debug component to the console. This method will only log if debug mode is
* This method will only log if debug mode is enabled. * enabled.
* *
* @param component The component to send. * @param component The component to send.
*/ */
@ -219,8 +214,8 @@ public class FreedomLogger implements Audience
} }
/** /**
* 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
* This method will only log if debug mode is enabled. * enabled.
* *
* @param message The message to send. * @param message The message to send.
*/ */
@ -231,8 +226,6 @@ public class FreedomLogger implements Audience
} }
@Override @Override
public void sendMessage(@NotNull final ComponentLike message) public void sendMessage(@NotNull final ComponentLike message)
{ {
@ -269,7 +262,7 @@ public class FreedomLogger implements Audience
public void sendMessage(@NotNull final SignedMessage signedMessage, final ChatType.@NotNull Bound boundChatType) public void sendMessage(@NotNull final SignedMessage signedMessage, final ChatType.@NotNull Bound boundChatType)
{ {
this.info( this.info(
signedMessage.message()); // TODO: We might want to investigate whether this logs the ENTIRE message, 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 // including unsigned & signed content, or only the signed part. This method was written in the assumption
// that it provided all content. // that it provided all content.
} }