1
0
Fork 0
mirror of https://github.com/xHyroM/lighteco.git synced 2024-11-23 07:21:04 +01:00

build: add spotless formatter (#9)

This commit is contained in:
Jozef Steinhübl 2024-07-16 18:22:32 +02:00 committed by GitHub
parent 23e73cb5da
commit 6cd7ad0901
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
108 changed files with 986 additions and 672 deletions

View file

@ -6,6 +6,7 @@ import dev.xhyrom.lighteco.api.manager.UserManager;
import dev.xhyrom.lighteco.api.messaging.MessagingService; import dev.xhyrom.lighteco.api.messaging.MessagingService;
import dev.xhyrom.lighteco.api.platform.Platform; import dev.xhyrom.lighteco.api.platform.Platform;
import dev.xhyrom.lighteco.api.platform.PlayerAdapter; import dev.xhyrom.lighteco.api.platform.PlayerAdapter;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.Optional; import java.util.Optional;

View file

@ -1,10 +1,11 @@
package dev.xhyrom.lighteco.api; package dev.xhyrom.lighteco.api;
import lombok.experimental.UtilityClass;
import org.checkerframework.checker.nullness.qual.NonNull;
import static org.jetbrains.annotations.ApiStatus.Internal; import static org.jetbrains.annotations.ApiStatus.Internal;
import lombok.experimental.UtilityClass;
import org.checkerframework.checker.nullness.qual.NonNull;
@UtilityClass @UtilityClass
public final class LightEcoProvider { public final class LightEcoProvider {
private static LightEco instance; private static LightEco instance;

View file

@ -1,6 +1,7 @@
package dev.xhyrom.lighteco.api.manager; package dev.xhyrom.lighteco.api.manager;
import dev.xhyrom.lighteco.api.model.currency.Currency; import dev.xhyrom.lighteco.api.model.currency.Currency;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
public interface CommandManager { public interface CommandManager {

View file

@ -1,6 +1,7 @@
package dev.xhyrom.lighteco.api.manager; package dev.xhyrom.lighteco.api.manager;
import dev.xhyrom.lighteco.api.model.currency.Currency; import dev.xhyrom.lighteco.api.model.currency.Currency;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;

View file

@ -1,6 +1,7 @@
package dev.xhyrom.lighteco.api.manager; package dev.xhyrom.lighteco.api.manager;
import dev.xhyrom.lighteco.api.model.user.User; import dev.xhyrom.lighteco.api.model.user.User;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
@ -9,6 +10,7 @@ import java.util.concurrent.CompletableFuture;
public interface UserManager { public interface UserManager {
@NonNull CompletableFuture<User> loadUser(@NonNull UUID uniqueId); @NonNull CompletableFuture<User> loadUser(@NonNull UUID uniqueId);
@NonNull CompletableFuture<User> loadUser(@NonNull UUID uniqueId, String username); @NonNull CompletableFuture<User> loadUser(@NonNull UUID uniqueId, String username);
@NonNull CompletableFuture<Void> saveUser(@NonNull User user); @NonNull CompletableFuture<Void> saveUser(@NonNull User user);

View file

@ -1,6 +1,7 @@
package dev.xhyrom.lighteco.api.messenger; package dev.xhyrom.lighteco.api.messenger;
import dev.xhyrom.lighteco.api.messenger.message.Message; import dev.xhyrom.lighteco.api.messenger.message.Message;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
public interface IncomingMessageConsumer { public interface IncomingMessageConsumer {

View file

@ -1,12 +1,12 @@
package dev.xhyrom.lighteco.api.messenger; package dev.xhyrom.lighteco.api.messenger;
import dev.xhyrom.lighteco.api.messenger.message.OutgoingMessage; import dev.xhyrom.lighteco.api.messenger.message.OutgoingMessage;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
public interface Messenger extends AutoCloseable { public interface Messenger extends AutoCloseable {
void sendOutgoingMessage(@NonNull OutgoingMessage message, boolean global); void sendOutgoingMessage(@NonNull OutgoingMessage message, boolean global);
@Override @Override
default void close() { default void close() {}
}
} }

View file

@ -1,6 +1,7 @@
package dev.xhyrom.lighteco.api.messenger.message.type; package dev.xhyrom.lighteco.api.messenger.message.type;
import dev.xhyrom.lighteco.api.messenger.message.Message; import dev.xhyrom.lighteco.api.messenger.message.Message;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.math.BigDecimal; import java.math.BigDecimal;

View file

@ -24,7 +24,8 @@ public interface Currency {
*/ */
default String[] getIdentifierAliases() { default String[] getIdentifierAliases() {
return new String[0]; return new String[0];
}; }
;
/** /**
* Returns the type of the currency, either {@link Type#LOCAL} or {@link Type#GLOBAL} * Returns the type of the currency, either {@link Type#LOCAL} or {@link Type#GLOBAL}
@ -79,7 +80,8 @@ public interface Currency {
*/ */
default BigDecimal calculateTax(User user, BigDecimal amount) { default BigDecimal calculateTax(User user, BigDecimal amount) {
return BigDecimal.ZERO; return BigDecimal.ZERO;
}; }
;
/** /**
* Represents the type of currency * Represents the type of currency

View file

@ -1,7 +1,9 @@
package dev.xhyrom.lighteco.api.model.user; package dev.xhyrom.lighteco.api.model.user;
import dev.xhyrom.lighteco.api.model.currency.Currency; import dev.xhyrom.lighteco.api.model.currency.Currency;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
@ -50,7 +52,8 @@ public interface User {
* @param amount the amount * @param amount the amount
* @throws IllegalArgumentException if the amount is negative * @throws IllegalArgumentException if the amount is negative
*/ */
void deposit(@NonNull Currency currency, @NonNull BigDecimal amount) throws IllegalArgumentException; void deposit(@NonNull Currency currency, @NonNull BigDecimal amount)
throws IllegalArgumentException;
/** /**
* Subtract the specified amount from the balance of this user for the specified currency. * Subtract the specified amount from the balance of this user for the specified currency.
@ -59,7 +62,8 @@ public interface User {
* @param amount the amount * @param amount the amount
* @throws IllegalArgumentException if the amount is negative * @throws IllegalArgumentException if the amount is negative
*/ */
void withdraw(@NonNull Currency currency, @NonNull BigDecimal amount) throws IllegalArgumentException; void withdraw(@NonNull Currency currency, @NonNull BigDecimal amount)
throws IllegalArgumentException;
/** /**
* Send a message to this user. * Send a message to this user.

View file

@ -1,6 +1,7 @@
package dev.xhyrom.lighteco.api.platform; package dev.xhyrom.lighteco.api.platform;
import dev.xhyrom.lighteco.api.model.user.User; import dev.xhyrom.lighteco.api.model.user.User;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;

View file

@ -2,6 +2,7 @@ package dev.xhyrom.lighteco.api.storage;
import dev.xhyrom.lighteco.api.model.currency.Currency; import dev.xhyrom.lighteco.api.model.currency.Currency;
import dev.xhyrom.lighteco.api.model.user.User; import dev.xhyrom.lighteco.api.model.user.User;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
@ -23,7 +24,10 @@ public interface StorageProvider {
void shutdown() throws Exception; void shutdown() throws Exception;
default void registerCurrency(@NonNull Currency currency) throws Exception {} default void registerCurrency(@NonNull Currency currency) throws Exception {}
@NonNull User loadUser(@NonNull UUID uniqueId, @Nullable String username) throws Exception; @NonNull User loadUser(@NonNull UUID uniqueId, @Nullable String username) throws Exception;
void saveUser(@NonNull User user) throws Exception; void saveUser(@NonNull User user) throws Exception;
void saveUsers(@NonNull User... users) throws Exception; void saveUsers(@NonNull User... users) throws Exception;
} }

View file

@ -3,6 +3,7 @@ import java.io.ByteArrayOutputStream
plugins { plugins {
id("java") id("java")
id("org.sonarqube") version "4.2.1.3168" id("org.sonarqube") version "4.2.1.3168"
id("com.diffplug.spotless") version "6.25.0"
} }
val majorVersion = 0 val majorVersion = 0
@ -10,6 +11,12 @@ val minorVersion = 1
val patchVersion = determinePatchVersion(project) val patchVersion = determinePatchVersion(project)
val commitHash = determineCommitHash(project) val commitHash = determineCommitHash(project)
defaultTasks("spotlessApply")
repositories {
mavenCentral()
}
allprojects { allprojects {
group = "dev.xhyrom" group = "dev.xhyrom"
version = "$majorVersion.$minorVersion.$patchVersion" version = "$majorVersion.$minorVersion.$patchVersion"
@ -32,6 +39,18 @@ subprojects {
} }
} }
spotless {
java {
importOrder()
removeUnusedImports()
palantirJavaFormat().style("AOSP")
formatAnnotations()
target("api/src/main/java/**", "common/src/main/java/**", "currency-money/src/main/java/**", "paper/src/main/java/**", "sponge-8/src/main/java/**", "test/**/src/main/java/**")
}
}
fun determinePatchVersion(project: Project): Int { fun determinePatchVersion(project: Project): Int {
val tagInfo = ByteArrayOutputStream() val tagInfo = ByteArrayOutputStream()

View file

@ -9,6 +9,7 @@ import dev.xhyrom.lighteco.api.platform.Platform;
import dev.xhyrom.lighteco.api.platform.PlayerAdapter; import dev.xhyrom.lighteco.api.platform.PlayerAdapter;
import dev.xhyrom.lighteco.common.api.impl.*; import dev.xhyrom.lighteco.common.api.impl.*;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.Optional; import java.util.Optional;
@ -62,7 +63,8 @@ public class LightEcoApi implements LightEco {
Class<?> expected = this.plugin.getContextManager().getPlayerClass(); Class<?> expected = this.plugin.getContextManager().getPlayerClass();
if (!expected.equals(playerClass)) { if (!expected.equals(playerClass)) {
throw new IllegalArgumentException("Expected player class " + expected.getName() + ", got " + playerClass.getName()); throw new IllegalArgumentException("Expected player class " + expected.getName()
+ ", got " + playerClass.getName());
} }
return (PlayerAdapter<T>) this.playerAdapter; return (PlayerAdapter<T>) this.playerAdapter;

View file

@ -3,25 +3,29 @@ package dev.xhyrom.lighteco.common.api.impl;
import dev.xhyrom.lighteco.api.manager.CommandManager; import dev.xhyrom.lighteco.api.manager.CommandManager;
import dev.xhyrom.lighteco.api.model.currency.Currency; import dev.xhyrom.lighteco.api.model.currency.Currency;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
public class ApiCommandManager extends ApiAbstractManager<dev.xhyrom.lighteco.common.command.CommandManager> implements CommandManager { public class ApiCommandManager
public ApiCommandManager(LightEcoPlugin plugin, dev.xhyrom.lighteco.common.command.CommandManager handle) { extends ApiAbstractManager<dev.xhyrom.lighteco.common.command.CommandManager>
implements CommandManager {
public ApiCommandManager(
LightEcoPlugin plugin, dev.xhyrom.lighteco.common.command.CommandManager handle) {
super(plugin, handle); super(plugin, handle);
} }
@Override @Override
public void registerCurrencyCommand(@NonNull Currency currency) { public void registerCurrencyCommand(@NonNull Currency currency) {
dev.xhyrom.lighteco.common.model.currency.Currency internal = this.plugin.getCurrencyManager() dev.xhyrom.lighteco.common.model.currency.Currency internal =
.getIfLoaded(currency.getIdentifier()); this.plugin.getCurrencyManager().getIfLoaded(currency.getIdentifier());
this.handle.register(internal, false); this.handle.register(internal, false);
} }
@Override @Override
public void registerCurrencyCommand(@NonNull Currency currency, boolean main) { public void registerCurrencyCommand(@NonNull Currency currency, boolean main) {
dev.xhyrom.lighteco.common.model.currency.Currency internal = this.plugin.getCurrencyManager() dev.xhyrom.lighteco.common.model.currency.Currency internal =
.getIfLoaded(currency.getIdentifier()); this.plugin.getCurrencyManager().getIfLoaded(currency.getIdentifier());
this.handle.register(internal, main); this.handle.register(internal, main);
} }

View file

@ -3,12 +3,17 @@ package dev.xhyrom.lighteco.common.api.impl;
import dev.xhyrom.lighteco.api.manager.CurrencyManager; import dev.xhyrom.lighteco.api.manager.CurrencyManager;
import dev.xhyrom.lighteco.api.model.currency.Currency; import dev.xhyrom.lighteco.api.model.currency.Currency;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.Collection; import java.util.Collection;
public class ApiCurrencyManager extends ApiAbstractManager<dev.xhyrom.lighteco.common.manager.currency.CurrencyManager> implements CurrencyManager { public class ApiCurrencyManager
public ApiCurrencyManager(LightEcoPlugin plugin, dev.xhyrom.lighteco.common.manager.currency.CurrencyManager handle) { extends ApiAbstractManager<dev.xhyrom.lighteco.common.manager.currency.CurrencyManager>
implements CurrencyManager {
public ApiCurrencyManager(
LightEcoPlugin plugin,
dev.xhyrom.lighteco.common.manager.currency.CurrencyManager handle) {
super(plugin, handle); super(plugin, handle);
} }
@ -18,9 +23,7 @@ public class ApiCurrencyManager extends ApiAbstractManager<dev.xhyrom.lighteco.c
@Override @Override
public @NonNull Collection<Currency> getRegisteredCurrencies() { public @NonNull Collection<Currency> getRegisteredCurrencies() {
return this.handle.values() return this.handle.values().stream().map(this::wrap).toList();
.stream().map(this::wrap)
.toList();
} }
@Override @Override
@ -30,7 +33,8 @@ public class ApiCurrencyManager extends ApiAbstractManager<dev.xhyrom.lighteco.c
@Override @Override
public void registerCurrency(@NonNull Currency currency) { public void registerCurrency(@NonNull Currency currency) {
dev.xhyrom.lighteco.common.model.currency.Currency internal = new dev.xhyrom.lighteco.common.model.currency.Currency(currency); dev.xhyrom.lighteco.common.model.currency.Currency internal =
new dev.xhyrom.lighteco.common.model.currency.Currency(currency);
this.handle.registerCurrency(internal); this.handle.registerCurrency(internal);
} }
} }

View file

@ -14,9 +14,8 @@ public class ApiMessagingService implements MessagingService {
@Override @Override
public void pushUserUpdate(User user, Currency currency) { public void pushUserUpdate(User user, Currency currency) {
dev.xhyrom.lighteco.common.model.currency.Currency internalCurrency = this.handle.getPlugin() dev.xhyrom.lighteco.common.model.currency.Currency internalCurrency =
.getCurrencyManager() this.handle.getPlugin().getCurrencyManager().getIfLoaded(currency.getIdentifier());
.getIfLoaded(currency.getIdentifier());
this.handle.pushUserUpdate(ApiUser.cast(user), internalCurrency); this.handle.pushUserUpdate(ApiUser.cast(user), internalCurrency);
} }

View file

@ -2,6 +2,7 @@ package dev.xhyrom.lighteco.common.api.impl;
import dev.xhyrom.lighteco.api.platform.Platform; import dev.xhyrom.lighteco.api.platform.Platform;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
public class ApiPlatform implements Platform { public class ApiPlatform implements Platform {

View file

@ -1,9 +1,10 @@
package dev.xhyrom.lighteco.common.api.impl; package dev.xhyrom.lighteco.common.api.impl;
import dev.xhyrom.lighteco.api.manager.ContextManager; import dev.xhyrom.lighteco.api.manager.ContextManager;
import dev.xhyrom.lighteco.api.model.user.User;
import dev.xhyrom.lighteco.api.manager.UserManager; import dev.xhyrom.lighteco.api.manager.UserManager;
import dev.xhyrom.lighteco.api.model.user.User;
import dev.xhyrom.lighteco.api.platform.PlayerAdapter; import dev.xhyrom.lighteco.api.platform.PlayerAdapter;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.UUID; import java.util.UUID;

View file

@ -2,7 +2,9 @@ package dev.xhyrom.lighteco.common.api.impl;
import dev.xhyrom.lighteco.api.model.currency.Currency; import dev.xhyrom.lighteco.api.model.currency.Currency;
import dev.xhyrom.lighteco.api.model.user.User; import dev.xhyrom.lighteco.api.model.user.User;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
@ -15,7 +17,8 @@ public class ApiUser implements User {
return ((ApiUser) u).handle; return ((ApiUser) u).handle;
} }
throw new IllegalArgumentException("Cannot cast " + u.getClass().getName() + " to " + ApiUser.class.getName()); throw new IllegalArgumentException(
"Cannot cast " + u.getClass().getName() + " to " + ApiUser.class.getName());
} }
private final dev.xhyrom.lighteco.common.model.user.User handle; private final dev.xhyrom.lighteco.common.model.user.User handle;
@ -36,36 +39,32 @@ public class ApiUser implements User {
@Override @Override
public @NonNull BigDecimal getBalance(@NonNull Currency currency) { public @NonNull BigDecimal getBalance(@NonNull Currency currency) {
dev.xhyrom.lighteco.common.model.currency.Currency internal = this.handle.getPlugin() dev.xhyrom.lighteco.common.model.currency.Currency internal =
.getCurrencyManager() this.handle.getPlugin().getCurrencyManager().getIfLoaded(currency.getIdentifier());
.getIfLoaded(currency.getIdentifier());
return this.handle.getBalance(internal); return this.handle.getBalance(internal);
} }
@Override @Override
public void setBalance(@NonNull Currency currency, @NonNull BigDecimal balance) { public void setBalance(@NonNull Currency currency, @NonNull BigDecimal balance) {
dev.xhyrom.lighteco.common.model.currency.Currency internal = this.handle.getPlugin() dev.xhyrom.lighteco.common.model.currency.Currency internal =
.getCurrencyManager() this.handle.getPlugin().getCurrencyManager().getIfLoaded(currency.getIdentifier());
.getIfLoaded(currency.getIdentifier());
this.handle.setBalance(internal, balance); this.handle.setBalance(internal, balance);
} }
@Override @Override
public void deposit(@NonNull Currency currency, @NonNull BigDecimal amount) { public void deposit(@NonNull Currency currency, @NonNull BigDecimal amount) {
dev.xhyrom.lighteco.common.model.currency.Currency internal = this.handle.getPlugin() dev.xhyrom.lighteco.common.model.currency.Currency internal =
.getCurrencyManager() this.handle.getPlugin().getCurrencyManager().getIfLoaded(currency.getIdentifier());
.getIfLoaded(currency.getIdentifier());
this.handle.deposit(internal, amount); this.handle.deposit(internal, amount);
} }
@Override @Override
public void withdraw(@NonNull Currency currency, @NonNull BigDecimal amount) { public void withdraw(@NonNull Currency currency, @NonNull BigDecimal amount) {
dev.xhyrom.lighteco.common.model.currency.Currency internal = this.handle.getPlugin() dev.xhyrom.lighteco.common.model.currency.Currency internal =
.getCurrencyManager() this.handle.getPlugin().getCurrencyManager().getIfLoaded(currency.getIdentifier());
.getIfLoaded(currency.getIdentifier());
this.handle.withdraw(internal, amount); this.handle.withdraw(internal, amount);
} }

View file

@ -3,14 +3,18 @@ package dev.xhyrom.lighteco.common.api.impl;
import dev.xhyrom.lighteco.api.manager.UserManager; import dev.xhyrom.lighteco.api.manager.UserManager;
import dev.xhyrom.lighteco.api.model.user.User; import dev.xhyrom.lighteco.api.model.user.User;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public class ApiUserManager extends ApiAbstractManager<dev.xhyrom.lighteco.common.manager.user.UserManager> implements UserManager { public class ApiUserManager
public ApiUserManager(LightEcoPlugin plugin, dev.xhyrom.lighteco.common.manager.user.UserManager handle) { extends ApiAbstractManager<dev.xhyrom.lighteco.common.manager.user.UserManager>
implements UserManager {
public ApiUserManager(
LightEcoPlugin plugin, dev.xhyrom.lighteco.common.manager.user.UserManager handle) {
super(plugin, handle); super(plugin, handle);
} }
@ -26,8 +30,7 @@ public class ApiUserManager extends ApiAbstractManager<dev.xhyrom.lighteco.commo
@Override @Override
public @NonNull CompletableFuture<User> loadUser(@NonNull UUID uniqueId, String username) { public @NonNull CompletableFuture<User> loadUser(@NonNull UUID uniqueId, String username) {
return this.plugin.getStorage().loadUser(uniqueId, username) return this.plugin.getStorage().loadUser(uniqueId, username).thenApply(this::wrap);
.thenApply(this::wrap);
} }
@Override @Override

View file

@ -10,9 +10,7 @@ public class ExpiringSet<T> {
private final long lifetime; private final long lifetime;
public ExpiringSet(long duration, TimeUnit unit) { public ExpiringSet(long duration, TimeUnit unit) {
this.cache = CacheBuilder.newBuilder() this.cache = CacheBuilder.newBuilder().expireAfterWrite(duration, unit).build();
.expireAfterWrite(duration, unit)
.build();
this.lifetime = unit.toMillis(duration); this.lifetime = unit.toMillis(duration);
} }

View file

@ -2,6 +2,4 @@ package dev.xhyrom.lighteco.common.cache;
import java.util.HashMap; import java.util.HashMap;
public class RedisBackedMap<T, U> extends HashMap<T, U> { public class RedisBackedMap<T, U> extends HashMap<T, U> {}
}

View file

@ -1,6 +1,7 @@
package dev.xhyrom.lighteco.common.command; package dev.xhyrom.lighteco.common.command;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import dev.xhyrom.lighteco.common.command.argument.type.OfflineUserArgument; import dev.xhyrom.lighteco.common.command.argument.type.OfflineUserArgument;
import dev.xhyrom.lighteco.common.command.exception.LockedUserException; import dev.xhyrom.lighteco.common.command.exception.LockedUserException;
import dev.xhyrom.lighteco.common.config.message.CurrencyMessageConfig; import dev.xhyrom.lighteco.common.config.message.CurrencyMessageConfig;
@ -8,7 +9,9 @@ import dev.xhyrom.lighteco.common.model.chat.CommandSender;
import dev.xhyrom.lighteco.common.model.currency.Currency; import dev.xhyrom.lighteco.common.model.currency.Currency;
import dev.xhyrom.lighteco.common.model.user.User; import dev.xhyrom.lighteco.common.model.user.User;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
@ -24,25 +27,25 @@ public class CommandHelper {
try { try {
target = OfflineUserArgument.getOfflineUser(context, "target"); target = OfflineUserArgument.getOfflineUser(context, "target");
} catch (LockedUserException e) { } catch (LockedUserException e) {
sender.sendMessage(MiniMessage.miniMessage().deserialize( sender.sendMessage(
plugin.getConfig().messages.wait MiniMessage.miniMessage().deserialize(plugin.getConfig().messages.wait));
));
} }
if (target == null || target.getUsername() == null) { if (target == null || target.getUsername() == null) {
String userName = context.getArgument("target", String.class); String userName = context.getArgument("target", String.class);
sender.sendMessage(MiniMessage.miniMessage().deserialize( sender.sendMessage(MiniMessage.miniMessage()
plugin.getConfig().messages.userNotFound, .deserialize(
Placeholder.parsed("username", userName) plugin.getConfig().messages.userNotFound,
)); Placeholder.parsed("username", userName)));
return null; return null;
} }
return target; return target;
} }
public static CurrencyMessageConfig getCurrencyMessageConfig(LightEcoPlugin plugin, Currency currency) { public static CurrencyMessageConfig getCurrencyMessageConfig(
LightEcoPlugin plugin, Currency currency) {
Map<String, CurrencyMessageConfig> config = plugin.getConfig().messages.currency; Map<String, CurrencyMessageConfig> config = plugin.getConfig().messages.currency;
CurrencyMessageConfig currencyMessageConfig = config.get(currency.getIdentifier()); CurrencyMessageConfig currencyMessageConfig = config.get(currency.getIdentifier());

View file

@ -4,6 +4,7 @@ import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.ParseResults; import com.mojang.brigadier.ParseResults;
import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.CommandSyntaxException;
import dev.xhyrom.lighteco.common.command.abstraction.Command; import dev.xhyrom.lighteco.common.command.abstraction.Command;
import dev.xhyrom.lighteco.common.commands.BalanceCommand; import dev.xhyrom.lighteco.common.commands.BalanceCommand;
import dev.xhyrom.lighteco.common.commands.CurrencyParentCommand; import dev.xhyrom.lighteco.common.commands.CurrencyParentCommand;
@ -12,7 +13,9 @@ import dev.xhyrom.lighteco.common.commands.PayCommand;
import dev.xhyrom.lighteco.common.model.chat.CommandSender; import dev.xhyrom.lighteco.common.model.chat.CommandSender;
import dev.xhyrom.lighteco.common.model.currency.Currency; import dev.xhyrom.lighteco.common.model.currency.Currency;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import lombok.Getter; import lombok.Getter;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent; import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
@ -24,17 +27,18 @@ import java.util.concurrent.*;
public class CommandManager { public class CommandManager {
protected final LightEcoPlugin plugin; protected final LightEcoPlugin plugin;
private final ExecutorService executor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder() private final ExecutorService executor =
.setDaemon(true) Executors.newSingleThreadExecutor(new ThreadFactoryBuilder()
.setNameFormat("lighteco-command-executor") .setDaemon(true)
.build() .setNameFormat("lighteco-command-executor")
); .build());
@Getter @Getter
private final CommandDispatcher<CommandSource> dispatcher = new CommandDispatcher<>(); private final CommandDispatcher<CommandSource> dispatcher = new CommandDispatcher<>();
@Getter @Getter
private final Set<UUID> locks = ConcurrentHashMap.newKeySet(); private final Set<UUID> locks = ConcurrentHashMap.newKeySet();
private final Map<UUID, UUID> locksMappings = new ConcurrentHashMap<>(); private final Map<UUID, UUID> locksMappings = new ConcurrentHashMap<>();
public CommandManager(LightEcoPlugin plugin) { public CommandManager(LightEcoPlugin plugin) {
@ -61,42 +65,47 @@ public class CommandManager {
public void execute(CommandSender sender, String name, String[] args) { public void execute(CommandSender sender, String name, String[] args) {
if (!sender.isConsole() && locks.contains(sender.getUniqueId())) { if (!sender.isConsole() && locks.contains(sender.getUniqueId())) {
sender.sendMessage(MiniMessage.miniMessage().deserialize( sender.sendMessage(
this.plugin.getConfig().messages.wait MiniMessage.miniMessage().deserialize(this.plugin.getConfig().messages.wait));
));
return; return;
} }
final CommandSource source = new CommandSource(this.plugin, sender); final CommandSource source = new CommandSource(this.plugin, sender);
final ParseResults<CommandSource> parseResults = dispatcher.parse( final ParseResults<CommandSource> parseResults = dispatcher.parse(
name + (args.length > 0 ? " " + String.join(" ", args) : ""), name + (args.length > 0 ? " " + String.join(" ", args) : ""), source);
source
);
if (!sender.isConsole()) if (!sender.isConsole()) locks.add(sender.getUniqueId());
locks.add(sender.getUniqueId());
CompletableFuture.runAsync(() -> { CompletableFuture.runAsync(
try { () -> {
dispatcher.execute(parseResults); try {
} catch (CommandSyntaxException e) { dispatcher.execute(parseResults);
this.sendError(sender, name, e); } catch (CommandSyntaxException e) {
} finally { this.sendError(sender, name, e);
if (!source.sender().isConsole()) { } finally {
this.plugin.getBootstrap().getLogger().debug("Removing lock for " + sender.getUsername()); if (!source.sender().isConsole()) {
this.plugin
.getBootstrap()
.getLogger()
.debug("Removing lock for " + sender.getUsername());
UUID target = locksMappings.get(sender.getUniqueId()); UUID target = locksMappings.get(sender.getUniqueId());
if (target != null) { if (target != null) {
locks.remove(target); locks.remove(target);
locksMappings.remove(sender.getUniqueId()); locksMappings.remove(sender.getUniqueId());
this.plugin.getBootstrap().getLogger().debug("Removing lock caused by " + sender.getUsername() + " for " + target); this.plugin
.getBootstrap()
.getLogger()
.debug("Removing lock caused by " + sender.getUsername()
+ " for " + target);
}
locks.remove(sender.getUniqueId());
}
} }
},
locks.remove(sender.getUniqueId()); executor);
}
}
}, executor);
} }
public void lockBySender(CommandSender sender, UUID target) { public void lockBySender(CommandSender sender, UUID target) {
@ -110,7 +119,10 @@ public class CommandManager {
if (e.getInput() != null && e.getCursor() >= 0) { if (e.getInput() != null && e.getCursor() >= 0) {
int j = Math.min(e.getInput().length(), e.getCursor()); int j = Math.min(e.getInput().length(), e.getCursor());
Component msg = Component.empty().color(NamedTextColor.GRAY).clickEvent(ClickEvent.clickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/" + name)); Component msg = Component.empty()
.color(NamedTextColor.GRAY)
.clickEvent(
ClickEvent.clickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/" + name));
if (j > 10) { if (j > 10) {
msg = msg.append(Component.text("...")); msg = msg.append(Component.text("..."));
@ -119,11 +131,15 @@ public class CommandManager {
msg = msg.append(Component.text(e.getInput().substring(Math.max(0, j - 10), j))); msg = msg.append(Component.text(e.getInput().substring(Math.max(0, j - 10), j)));
if (j < e.getInput().length()) { if (j < e.getInput().length()) {
Component component = Component.text(e.getInput().substring(j)).color(NamedTextColor.RED).decorate(TextDecoration.UNDERLINED); Component component = Component.text(e.getInput().substring(j))
.color(NamedTextColor.RED)
.decorate(TextDecoration.UNDERLINED);
msg = msg.append(component); msg = msg.append(component);
} }
msg = msg.append(Component.translatable("command.context.here").color(NamedTextColor.RED).decorate(TextDecoration.ITALIC)); msg = msg.append(Component.translatable("command.context.here")
.color(NamedTextColor.RED)
.decorate(TextDecoration.ITALIC));
sender.sendMessage(msg); sender.sendMessage(msg);
} }
} }

View file

@ -2,7 +2,7 @@ package dev.xhyrom.lighteco.common.command;
import dev.xhyrom.lighteco.common.model.chat.CommandSender; import dev.xhyrom.lighteco.common.model.chat.CommandSender;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
public record CommandSource(@NonNull LightEcoPlugin plugin, @NonNull CommandSender sender) { public record CommandSource(@NonNull LightEcoPlugin plugin, @NonNull CommandSender sender) {}
}

View file

@ -2,8 +2,11 @@ package dev.xhyrom.lighteco.common.command.abstraction;
import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.CommandNode; import com.mojang.brigadier.tree.CommandNode;
import dev.xhyrom.lighteco.common.command.CommandSource; import dev.xhyrom.lighteco.common.command.CommandSource;
import lombok.Getter; import lombok.Getter;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.ArrayList; import java.util.ArrayList;
@ -12,14 +15,11 @@ import java.util.List;
@Getter @Getter
public abstract class Command { public abstract class Command {
@NonNull @NonNull protected final String name;
protected final String name;
@NonNull @NonNull private final String description;
private final String description;
@NonNull @NonNull private final List<String> aliases = new ArrayList<>();
private final List<String> aliases = new ArrayList<>();
public Command(@NonNull String name, @NonNull String description, String... aliases) { public Command(@NonNull String name, @NonNull String description, String... aliases) {
this.name = name; this.name = name;

View file

@ -4,6 +4,7 @@ import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.arguments.ArgumentType; import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.CommandSyntaxException;
import dev.xhyrom.lighteco.common.command.CommandSource; import dev.xhyrom.lighteco.common.command.CommandSource;
import dev.xhyrom.lighteco.common.command.exception.LockedUserException; import dev.xhyrom.lighteco.common.command.exception.LockedUserException;
import dev.xhyrom.lighteco.common.model.chat.CommandSender; import dev.xhyrom.lighteco.common.model.chat.CommandSender;
@ -15,7 +16,8 @@ import java.util.UUID;
public class OfflineUserArgument implements ArgumentType<String> { public class OfflineUserArgument implements ArgumentType<String> {
private OfflineUserArgument() {} private OfflineUserArgument() {}
public static User getOfflineUser(CommandContext<CommandSource> context, String name) throws LockedUserException { public static User getOfflineUser(CommandContext<CommandSource> context, String name)
throws LockedUserException {
String userName = context.getArgument(name, String.class); String userName = context.getArgument(name, String.class);
LightEcoPlugin plugin = context.getSource().plugin(); LightEcoPlugin plugin = context.getSource().plugin();
CommandSender sender = context.getSource().sender(); CommandSender sender = context.getSource().sender();
@ -25,7 +27,8 @@ public class OfflineUserArgument implements ArgumentType<String> {
return null; return null;
} }
if (sender.getUniqueId() != uniqueId && plugin.getCommandManager().getLocks().contains(uniqueId)) { if (sender.getUniqueId() != uniqueId
&& plugin.getCommandManager().getLocks().contains(uniqueId)) {
throw new LockedUserException(uniqueId); throw new LockedUserException(uniqueId);
} }

View file

@ -4,6 +4,7 @@ import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.suggestion.SuggestionProvider; import com.mojang.brigadier.suggestion.SuggestionProvider;
import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder; import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import dev.xhyrom.lighteco.common.command.CommandSource; import dev.xhyrom.lighteco.common.command.CommandSource;
import dev.xhyrom.lighteco.common.model.user.User; import dev.xhyrom.lighteco.common.model.user.User;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
@ -17,7 +18,8 @@ public class OfflineUserSuggestionProvider implements SuggestionProvider<Command
} }
@Override @Override
public CompletableFuture<Suggestions> getSuggestions(CommandContext<CommandSource> context, SuggestionsBuilder builder) { public CompletableFuture<Suggestions> getSuggestions(
CommandContext<CommandSource> context, SuggestionsBuilder builder) {
LightEcoPlugin plugin = context.getSource().plugin(); LightEcoPlugin plugin = context.getSource().plugin();
String remaining = builder.getRemaining(); String remaining = builder.getRemaining();

View file

@ -1,8 +1,13 @@
package dev.xhyrom.lighteco.common.commands; package dev.xhyrom.lighteco.common.commands;
import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
import static dev.xhyrom.lighteco.common.command.CommandHelper.*;
import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.RequiredArgumentBuilder; import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.mojang.brigadier.tree.CommandNode; import com.mojang.brigadier.tree.CommandNode;
import dev.xhyrom.lighteco.common.command.CommandSource; import dev.xhyrom.lighteco.common.command.CommandSource;
import dev.xhyrom.lighteco.common.command.abstraction.Command; import dev.xhyrom.lighteco.common.command.abstraction.Command;
import dev.xhyrom.lighteco.common.command.suggestion.type.OfflineUserSuggestionProvider; import dev.xhyrom.lighteco.common.command.suggestion.type.OfflineUserSuggestionProvider;
@ -10,15 +15,14 @@ import dev.xhyrom.lighteco.common.model.chat.CommandSender;
import dev.xhyrom.lighteco.common.model.currency.Currency; import dev.xhyrom.lighteco.common.model.currency.Currency;
import dev.xhyrom.lighteco.common.model.user.User; import dev.xhyrom.lighteco.common.model.user.User;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.math.BigDecimal; import java.math.BigDecimal;
import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
import static dev.xhyrom.lighteco.common.command.CommandHelper.*;
public class BalanceCommand extends Command { public class BalanceCommand extends Command {
private final Currency currency; private final Currency currency;
@ -35,32 +39,36 @@ public class BalanceCommand extends Command {
@Override @Override
public CommandNode<CommandSource> build() { public CommandNode<CommandSource> build() {
return builder() return builder()
.then( .then(RequiredArgumentBuilder.<CommandSource, String>argument(
RequiredArgumentBuilder.<CommandSource, String>argument("target", StringArgumentType.word()) "target", StringArgumentType.word())
.suggests(OfflineUserSuggestionProvider.create()) .suggests(OfflineUserSuggestionProvider.create())
.requires((source) -> source.sender().eligible("lighteco.currency."+currency.getIdentifier()+".command.balance.others")) .requires((source) -> source.sender()
.executes(context -> { .eligible("lighteco.currency." + currency.getIdentifier()
LightEcoPlugin plugin = context.getSource().plugin(); + ".command.balance.others"))
CommandSender sender = context.getSource().sender(); .executes(context -> {
LightEcoPlugin plugin = context.getSource().plugin();
CommandSender sender = context.getSource().sender();
final User target = getUser(context); final User target = getUser(context);
if (target == null) if (target == null) return SINGLE_SUCCESS;
return SINGLE_SUCCESS;
BigDecimal balance = target.getBalance(currency); BigDecimal balance = target.getBalance(currency);
sender.sendMessage( sender.sendMessage(MiniMessage.miniMessage()
MiniMessage.miniMessage().deserialize( .deserialize(
getCurrencyMessageConfig(plugin, currency).balanceOthers, getCurrencyMessageConfig(plugin, currency)
Placeholder.parsed("currency", currency.getIdentifier()), .balanceOthers,
Placeholder.parsed("target", target.getUsername()), Placeholder.parsed(
Placeholder.parsed("balance", balance.toPlainString()) "currency", currency.getIdentifier()),
) Placeholder.parsed("target", target.getUsername()),
); Placeholder.parsed(
"balance", balance.toPlainString())));
return SINGLE_SUCCESS; return SINGLE_SUCCESS;
})) }))
.requires((source) -> source.sender().eligible("lighteco.currency."+currency.getIdentifier()+".command.balance")) .requires((source) -> source.sender()
.eligible("lighteco.currency." + currency.getIdentifier()
+ ".command.balance"))
.executes(context -> { .executes(context -> {
LightEcoPlugin plugin = context.getSource().plugin(); LightEcoPlugin plugin = context.getSource().plugin();
CommandSender sender = context.getSource().sender(); CommandSender sender = context.getSource().sender();
@ -68,13 +76,11 @@ public class BalanceCommand extends Command {
User user = plugin.getUserManager().getIfLoaded(sender.getUniqueId()); User user = plugin.getUserManager().getIfLoaded(sender.getUniqueId());
BigDecimal balance = user.getBalance(currency); BigDecimal balance = user.getBalance(currency);
sender.sendMessage( sender.sendMessage(MiniMessage.miniMessage()
MiniMessage.miniMessage().deserialize( .deserialize(
getCurrencyMessageConfig(plugin, currency).balance, getCurrencyMessageConfig(plugin, currency).balance,
Placeholder.parsed("currency", currency.getIdentifier()), Placeholder.parsed("currency", currency.getIdentifier()),
Placeholder.parsed("balance", balance.toPlainString()) Placeholder.parsed("balance", balance.toPlainString())));
)
);
return SINGLE_SUCCESS; return SINGLE_SUCCESS;
}) })

View file

@ -1,30 +1,31 @@
package dev.xhyrom.lighteco.common.commands; package dev.xhyrom.lighteco.common.commands;
import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
import static dev.xhyrom.lighteco.common.command.CommandHelper.getCurrencyMessageConfig;
import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.CommandNode; import com.mojang.brigadier.tree.CommandNode;
import dev.xhyrom.lighteco.common.command.CommandSource; import dev.xhyrom.lighteco.common.command.CommandSource;
import dev.xhyrom.lighteco.common.command.abstraction.Command; import dev.xhyrom.lighteco.common.command.abstraction.Command;
import dev.xhyrom.lighteco.common.model.chat.CommandSender; import dev.xhyrom.lighteco.common.model.chat.CommandSender;
import dev.xhyrom.lighteco.common.model.currency.Currency; import dev.xhyrom.lighteco.common.model.currency.Currency;
import dev.xhyrom.lighteco.common.model.user.User; import dev.xhyrom.lighteco.common.model.user.User;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.math.BigDecimal; import java.math.BigDecimal;
import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
import static dev.xhyrom.lighteco.common.command.CommandHelper.getCurrencyMessageConfig;
public class CurrencyParentCommand extends Command { public class CurrencyParentCommand extends Command {
private final Currency currency; private final Currency currency;
public CurrencyParentCommand(@NonNull Currency currency) { public CurrencyParentCommand(@NonNull Currency currency) {
super( super(currency.getIdentifier(), currency.getIdentifier());
currency.getIdentifier(),
currency.getIdentifier()
);
this.currency = currency; this.currency = currency;
} }
@ -43,13 +44,11 @@ public class CurrencyParentCommand extends Command {
User user = plugin.getUserManager().getIfLoaded(sender.getUniqueId()); User user = plugin.getUserManager().getIfLoaded(sender.getUniqueId());
BigDecimal balance = user.getBalance(currency); BigDecimal balance = user.getBalance(currency);
sender.sendMessage( sender.sendMessage(MiniMessage.miniMessage()
MiniMessage.miniMessage().deserialize( .deserialize(
getCurrencyMessageConfig(plugin, currency).balance, getCurrencyMessageConfig(plugin, currency).balance,
Placeholder.parsed("currency", currency.getIdentifier()), Placeholder.parsed("currency", currency.getIdentifier()),
Placeholder.parsed("balance", balance.toPlainString()) Placeholder.parsed("balance", balance.toPlainString())));
)
);
return SINGLE_SUCCESS; return SINGLE_SUCCESS;
}); });

View file

@ -1,11 +1,16 @@
package dev.xhyrom.lighteco.common.commands; package dev.xhyrom.lighteco.common.commands;
import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
import static dev.xhyrom.lighteco.common.command.CommandHelper.*;
import com.mojang.brigadier.arguments.DoubleArgumentType; import com.mojang.brigadier.arguments.DoubleArgumentType;
import com.mojang.brigadier.arguments.IntegerArgumentType; import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.RequiredArgumentBuilder; import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.tree.CommandNode; import com.mojang.brigadier.tree.CommandNode;
import dev.xhyrom.lighteco.api.exception.CannotBeGreaterThan; import dev.xhyrom.lighteco.api.exception.CannotBeGreaterThan;
import dev.xhyrom.lighteco.common.command.CommandSource; import dev.xhyrom.lighteco.common.command.CommandSource;
import dev.xhyrom.lighteco.common.command.abstraction.Command; import dev.xhyrom.lighteco.common.command.abstraction.Command;
@ -14,16 +19,15 @@ import dev.xhyrom.lighteco.common.model.chat.CommandSender;
import dev.xhyrom.lighteco.common.model.currency.Currency; import dev.xhyrom.lighteco.common.model.currency.Currency;
import dev.xhyrom.lighteco.common.model.user.User; import dev.xhyrom.lighteco.common.model.user.User;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
import static dev.xhyrom.lighteco.common.command.CommandHelper.*;
public class GiveCommand extends Command { public class GiveCommand extends Command {
private static final MiniMessage miniMessage = MiniMessage.miniMessage(); private static final MiniMessage miniMessage = MiniMessage.miniMessage();
private final Currency currency; private final Currency currency;
@ -43,60 +47,66 @@ public class GiveCommand extends Command {
final CommandSender sender = context.getSource().sender(); final CommandSender sender = context.getSource().sender();
final User target = getUser(context); final User target = getUser(context);
if (target == null) if (target == null) return;
return;
BigDecimal amount = BigDecimal.valueOf(currency.fractionalDigits() > 0 BigDecimal amount = BigDecimal.valueOf(
? context.getArgument("amount", Double.class) currency.fractionalDigits() > 0
: context.getArgument("amount", Integer.class)); ? context.getArgument("amount", Double.class)
: context.getArgument("amount", Integer.class));
amount = amount.setScale(currency.fractionalDigits(), RoundingMode.DOWN); amount = amount.setScale(currency.fractionalDigits(), RoundingMode.DOWN);
try { try {
target.deposit(currency, amount); target.deposit(currency, amount);
} catch (CannotBeGreaterThan e) { } catch (CannotBeGreaterThan e) {
sender.sendMessage( sender.sendMessage(miniMessage.deserialize(
miniMessage.deserialize( getCurrencyMessageConfig(plugin, this.currency).cannotBeGreaterThan,
getCurrencyMessageConfig(plugin, this.currency).cannotBeGreaterThan, Placeholder.parsed("max", plugin.getConfig().maximumBalance.toPlainString())));
Placeholder.parsed("max", plugin.getConfig().maximumBalance.toPlainString())
)
);
return; return;
} }
sender.sendMessage( sender.sendMessage(miniMessage.deserialize(
miniMessage.deserialize( getCurrencyMessageConfig(plugin, this.currency).set,
getCurrencyMessageConfig(plugin, this.currency).set, Placeholder.parsed("currency", currency.getIdentifier()),
Placeholder.parsed("currency", currency.getIdentifier()), Placeholder.parsed("target", target.getUsername()),
Placeholder.parsed("target", target.getUsername()), Placeholder.parsed("amount", amount.toPlainString())));
Placeholder.parsed("amount", amount.toPlainString())
)
);
} }
@Override @Override
public CommandNode<CommandSource> build() { public CommandNode<CommandSource> build() {
if (currency.fractionalDigits() > 0) { if (currency.fractionalDigits() > 0) {
return builder() return builder()
.requires((source) -> source.sender().eligible("lighteco.currency." + currency.getIdentifier() + ".command.give")) .requires((source) -> source.sender()
.then(RequiredArgumentBuilder.<CommandSource, String>argument("target", StringArgumentType.word()) .eligible("lighteco.currency." + currency.getIdentifier()
+ ".command.give"))
.then(RequiredArgumentBuilder.<CommandSource, String>argument(
"target", StringArgumentType.word())
.suggests(OfflineUserSuggestionProvider.create()) .suggests(OfflineUserSuggestionProvider.create())
.then(RequiredArgumentBuilder.<CommandSource, Double>argument("amount", DoubleArgumentType.doubleArg(1)) .then(RequiredArgumentBuilder.<CommandSource, Double>argument(
.requires((source) -> source.sender().eligible("lighteco.currency." + currency.getIdentifier() + ".command.give")) "amount", DoubleArgumentType.doubleArg(1))
.requires((source) -> source.sender()
.eligible("lighteco.currency."
+ currency.getIdentifier() + ".command.give"))
.executes(c -> { .executes(c -> {
execute(c); execute(c);
return SINGLE_SUCCESS; return SINGLE_SUCCESS;
}))) })))
.build(); .build();
} }
return builder() return builder()
.requires((source) -> source.sender().eligible("lighteco.currency." + currency.getIdentifier() + ".command.give")) .requires((source) -> source.sender()
.then(RequiredArgumentBuilder.<CommandSource, String>argument("target", StringArgumentType.word()) .eligible(
"lighteco.currency." + currency.getIdentifier() + ".command.give"))
.then(RequiredArgumentBuilder.<CommandSource, String>argument(
"target", StringArgumentType.word())
.suggests(OfflineUserSuggestionProvider.create()) .suggests(OfflineUserSuggestionProvider.create())
.then(RequiredArgumentBuilder.<CommandSource, Integer>argument("amount", IntegerArgumentType.integer(1)) .then(RequiredArgumentBuilder.<CommandSource, Integer>argument(
.requires((source) -> source.sender().eligible("lighteco.currency." + currency.getIdentifier() + ".command.give")) "amount", IntegerArgumentType.integer(1))
.requires((source) -> source.sender()
.eligible("lighteco.currency." + currency.getIdentifier()
+ ".command.give"))
.executes(c -> { .executes(c -> {
execute(c); execute(c);
return SINGLE_SUCCESS; return SINGLE_SUCCESS;

View file

@ -1,15 +1,17 @@
package dev.xhyrom.lighteco.common.commands; package dev.xhyrom.lighteco.common.commands;
import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
import com.mojang.brigadier.tree.CommandNode; import com.mojang.brigadier.tree.CommandNode;
import dev.xhyrom.lighteco.common.command.CommandSource; import dev.xhyrom.lighteco.common.command.CommandSource;
import dev.xhyrom.lighteco.common.command.abstraction.Command; import dev.xhyrom.lighteco.common.command.abstraction.Command;
import dev.xhyrom.lighteco.common.model.chat.CommandSender; import dev.xhyrom.lighteco.common.model.chat.CommandSender;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
public class InfoCommand extends Command { public class InfoCommand extends Command {
public InfoCommand() { public InfoCommand() {
super("lighteco", "LightEco information"); super("lighteco", "LightEco information");
@ -23,11 +25,13 @@ public class InfoCommand extends Command {
LightEcoPlugin plugin = context.getSource().plugin(); LightEcoPlugin plugin = context.getSource().plugin();
CommandSender sender = context.getSource().sender(); CommandSender sender = context.getSource().sender();
sender.sendMessage(MiniMessage.miniMessage().deserialize( sender.sendMessage(MiniMessage.miniMessage()
"<#fa5246><bold>LightEco</bold></#fa5246> <dark_gray>(<#d6766f>v<version><dark_gray>) <white>on <#d6766f><platform>", .deserialize(
Placeholder.parsed("version", plugin.getBootstrap().getVersion()), "<#fa5246><bold>LightEco</bold></#fa5246> <dark_gray>(<#d6766f>v<version><dark_gray>) <white>on <#d6766f><platform>",
Placeholder.parsed("platform", plugin.getPlatformType().getName()) Placeholder.parsed(
)); "version", plugin.getBootstrap().getVersion()),
Placeholder.parsed(
"platform", plugin.getPlatformType().getName())));
return SINGLE_SUCCESS; return SINGLE_SUCCESS;
}) })

View file

@ -1,11 +1,16 @@
package dev.xhyrom.lighteco.common.commands; package dev.xhyrom.lighteco.common.commands;
import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
import static dev.xhyrom.lighteco.common.command.CommandHelper.*;
import com.mojang.brigadier.arguments.DoubleArgumentType; import com.mojang.brigadier.arguments.DoubleArgumentType;
import com.mojang.brigadier.arguments.IntegerArgumentType; import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.RequiredArgumentBuilder; import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.tree.CommandNode; import com.mojang.brigadier.tree.CommandNode;
import dev.xhyrom.lighteco.api.exception.CannotBeGreaterThan; import dev.xhyrom.lighteco.api.exception.CannotBeGreaterThan;
import dev.xhyrom.lighteco.common.command.CommandSource; import dev.xhyrom.lighteco.common.command.CommandSource;
import dev.xhyrom.lighteco.common.command.abstraction.Command; import dev.xhyrom.lighteco.common.command.abstraction.Command;
@ -14,16 +19,15 @@ import dev.xhyrom.lighteco.common.model.chat.CommandSender;
import dev.xhyrom.lighteco.common.model.currency.Currency; import dev.xhyrom.lighteco.common.model.currency.Currency;
import dev.xhyrom.lighteco.common.model.user.User; import dev.xhyrom.lighteco.common.model.user.User;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
import static dev.xhyrom.lighteco.common.command.CommandHelper.*;
public class PayCommand extends Command { public class PayCommand extends Command {
private static final MiniMessage miniMessage = MiniMessage.miniMessage(); private static final MiniMessage miniMessage = MiniMessage.miniMessage();
private final Currency currency; private final Currency currency;
@ -43,12 +47,12 @@ public class PayCommand extends Command {
final CommandSender sender = context.getSource().sender(); final CommandSender sender = context.getSource().sender();
final User target = getUser(context); final User target = getUser(context);
if (target == null) if (target == null) return;
return;
BigDecimal amount = BigDecimal.valueOf(currency.fractionalDigits() > 0 BigDecimal amount = BigDecimal.valueOf(
? context.getArgument("amount", Double.class) currency.fractionalDigits() > 0
: context.getArgument("amount", Integer.class)); ? context.getArgument("amount", Double.class)
: context.getArgument("amount", Integer.class));
amount = amount.setScale(currency.fractionalDigits(), RoundingMode.DOWN); amount = amount.setScale(currency.fractionalDigits(), RoundingMode.DOWN);
@ -58,9 +62,8 @@ public class PayCommand extends Command {
} }
if (user.getBalance(this.currency).compareTo(amount) < 0) { if (user.getBalance(this.currency).compareTo(amount) < 0) {
sender.sendMessage( sender.sendMessage(miniMessage.deserialize(
miniMessage.deserialize(getCurrencyMessageConfig(plugin, this.currency).notEnoughMoney) getCurrencyMessageConfig(plugin, this.currency).notEnoughMoney));
);
return; return;
} }
@ -76,12 +79,9 @@ public class PayCommand extends Command {
target.deposit(currency, taxedAmount); target.deposit(currency, taxedAmount);
user.withdraw(currency, amount); user.withdraw(currency, amount);
} catch (CannotBeGreaterThan e) { } catch (CannotBeGreaterThan e) {
sender.sendMessage( sender.sendMessage(miniMessage.deserialize(
miniMessage.deserialize( getCurrencyMessageConfig(plugin, this.currency).cannotBeGreaterThan,
getCurrencyMessageConfig(plugin, this.currency).cannotBeGreaterThan, Placeholder.parsed("max", plugin.getConfig().maximumBalance.toPlainString())));
Placeholder.parsed("max", plugin.getConfig().maximumBalance.toPlainString())
)
);
return; return;
} }
@ -94,53 +94,63 @@ public class PayCommand extends Command {
? getCurrencyMessageConfig(plugin, this.currency).payReceivedWithTax ? getCurrencyMessageConfig(plugin, this.currency).payReceivedWithTax
: getCurrencyMessageConfig(plugin, this.currency).payReceived; : getCurrencyMessageConfig(plugin, this.currency).payReceived;
sender.sendMessage( sender.sendMessage(miniMessage.deserialize(
miniMessage.deserialize( template,
template, Placeholder.parsed("currency", currency.getIdentifier()),
Placeholder.parsed("currency", currency.getIdentifier()), Placeholder.parsed("target", target.getUsername()),
Placeholder.parsed("target", target.getUsername()), Placeholder.parsed("amount", amount.toPlainString()),
Placeholder.parsed("amount", amount.toPlainString()), Placeholder.parsed("taxed_amount", taxedAmount.toPlainString()),
Placeholder.parsed("taxed_amount", taxedAmount.toPlainString()), Placeholder.parsed("sender_balance", user.getBalance(currency).toPlainString()),
Placeholder.parsed("sender_balance", user.getBalance(currency).toPlainString()), Placeholder.parsed(
Placeholder.parsed("receiver_balance", target.getBalance(currency).toPlainString()) "receiver_balance", target.getBalance(currency).toPlainString())));
)
);
target.sendMessage( target.sendMessage(miniMessage.deserialize(
miniMessage.deserialize( templateReceived,
templateReceived, Placeholder.parsed("currency", currency.getIdentifier()),
Placeholder.parsed("currency", currency.getIdentifier()), Placeholder.parsed("sender", user.getUsername()),
Placeholder.parsed("sender", user.getUsername()), Placeholder.parsed("amount", amount.toPlainString()),
Placeholder.parsed("amount", amount.toPlainString()), Placeholder.parsed("taxed_amount", taxedAmount.toPlainString()),
Placeholder.parsed("taxed_amount", taxedAmount.toPlainString()), Placeholder.parsed("sender_balance", user.getBalance(currency).toPlainString()),
Placeholder.parsed("sender_balance", user.getBalance(currency).toPlainString()), Placeholder.parsed(
Placeholder.parsed("receiver_balance", target.getBalance(currency).toPlainString()) "receiver_balance", target.getBalance(currency).toPlainString())));
)
);
} }
@Override @Override
public CommandNode<CommandSource> build() { public CommandNode<CommandSource> build() {
if (currency.fractionalDigits() > 0) { if (currency.fractionalDigits() > 0) {
return builder() return builder()
.requires((source) -> !source.sender().isConsole() && source.sender().eligible("lighteco.currency." + currency.getIdentifier() + ".command.pay")) .requires((source) -> !source.sender().isConsole()
.then(RequiredArgumentBuilder.<CommandSource, String>argument("target", StringArgumentType.word()) && source.sender()
.eligible("lighteco.currency." + currency.getIdentifier()
+ ".command.pay"))
.then(RequiredArgumentBuilder.<CommandSource, String>argument(
"target", StringArgumentType.word())
.suggests(OfflineUserSuggestionProvider.create()) .suggests(OfflineUserSuggestionProvider.create())
.then(RequiredArgumentBuilder.<CommandSource, Double>argument("amount", DoubleArgumentType.doubleArg(1)) .then(RequiredArgumentBuilder.<CommandSource, Double>argument(
.requires((source) -> source.sender().eligible("lighteco.currency." + currency.getIdentifier() + ".command.pay")) "amount", DoubleArgumentType.doubleArg(1))
.requires((source) -> source.sender()
.eligible("lighteco.currency."
+ currency.getIdentifier() + ".command.pay"))
.executes(c -> { .executes(c -> {
execute(c); execute(c);
return SINGLE_SUCCESS; return SINGLE_SUCCESS;
}))) })))
.build(); .build();
} }
return builder() return builder()
.requires((source) -> !source.sender().isConsole() && source.sender().eligible("lighteco.currency." + currency.getIdentifier() + ".command.pay")) .requires((source) -> !source.sender().isConsole()
.then(RequiredArgumentBuilder.<CommandSource, String>argument("target", StringArgumentType.word()) && source.sender()
.eligible("lighteco.currency." + currency.getIdentifier()
+ ".command.pay"))
.then(RequiredArgumentBuilder.<CommandSource, String>argument(
"target", StringArgumentType.word())
.suggests(OfflineUserSuggestionProvider.create()) .suggests(OfflineUserSuggestionProvider.create())
.then(RequiredArgumentBuilder.<CommandSource, Integer>argument("amount", IntegerArgumentType.integer(1)) .then(RequiredArgumentBuilder.<CommandSource, Integer>argument(
.requires((source) -> source.sender().eligible("lighteco.currency." + currency.getIdentifier() + ".command.pay")) "amount", IntegerArgumentType.integer(1))
.requires((source) -> source.sender()
.eligible("lighteco.currency." + currency.getIdentifier()
+ ".command.pay"))
.executes(c -> { .executes(c -> {
execute(c); execute(c);
return SINGLE_SUCCESS; return SINGLE_SUCCESS;

View file

@ -1,11 +1,16 @@
package dev.xhyrom.lighteco.common.commands; package dev.xhyrom.lighteco.common.commands;
import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
import static dev.xhyrom.lighteco.common.command.CommandHelper.*;
import com.mojang.brigadier.arguments.DoubleArgumentType; import com.mojang.brigadier.arguments.DoubleArgumentType;
import com.mojang.brigadier.arguments.IntegerArgumentType; import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.RequiredArgumentBuilder; import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.tree.CommandNode; import com.mojang.brigadier.tree.CommandNode;
import dev.xhyrom.lighteco.api.exception.CannotBeGreaterThan; import dev.xhyrom.lighteco.api.exception.CannotBeGreaterThan;
import dev.xhyrom.lighteco.common.command.CommandSource; import dev.xhyrom.lighteco.common.command.CommandSource;
import dev.xhyrom.lighteco.common.command.abstraction.Command; import dev.xhyrom.lighteco.common.command.abstraction.Command;
@ -14,16 +19,15 @@ import dev.xhyrom.lighteco.common.model.chat.CommandSender;
import dev.xhyrom.lighteco.common.model.currency.Currency; import dev.xhyrom.lighteco.common.model.currency.Currency;
import dev.xhyrom.lighteco.common.model.user.User; import dev.xhyrom.lighteco.common.model.user.User;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
import static dev.xhyrom.lighteco.common.command.CommandHelper.*;
public class SetCommand extends Command { public class SetCommand extends Command {
private static final MiniMessage miniMessage = MiniMessage.miniMessage(); private static final MiniMessage miniMessage = MiniMessage.miniMessage();
private final Currency currency; private final Currency currency;
@ -43,60 +47,65 @@ public class SetCommand extends Command {
final CommandSender sender = context.getSource().sender(); final CommandSender sender = context.getSource().sender();
final User target = getUser(context); final User target = getUser(context);
if (target == null) if (target == null) return;
return;
BigDecimal amount = BigDecimal.valueOf(currency.fractionalDigits() > 0 BigDecimal amount = BigDecimal.valueOf(
? context.getArgument("amount", Double.class) currency.fractionalDigits() > 0
: context.getArgument("amount", Integer.class)); ? context.getArgument("amount", Double.class)
: context.getArgument("amount", Integer.class));
amount = amount.setScale(currency.fractionalDigits(), RoundingMode.DOWN); amount = amount.setScale(currency.fractionalDigits(), RoundingMode.DOWN);
try { try {
target.setBalance(currency, amount); target.setBalance(currency, amount);
} catch (CannotBeGreaterThan e) { } catch (CannotBeGreaterThan e) {
sender.sendMessage( sender.sendMessage(miniMessage.deserialize(
miniMessage.deserialize( getCurrencyMessageConfig(plugin, this.currency).cannotBeGreaterThan,
getCurrencyMessageConfig(plugin, this.currency).cannotBeGreaterThan, Placeholder.parsed("max", plugin.getConfig().maximumBalance.toPlainString())));
Placeholder.parsed("max", plugin.getConfig().maximumBalance.toPlainString())
)
);
return; return;
} }
sender.sendMessage( sender.sendMessage(miniMessage.deserialize(
miniMessage.deserialize( getCurrencyMessageConfig(plugin, this.currency).set,
getCurrencyMessageConfig(plugin, this.currency).set, Placeholder.parsed("currency", currency.getIdentifier()),
Placeholder.parsed("currency", currency.getIdentifier()), Placeholder.parsed("target", target.getUsername()),
Placeholder.parsed("target", target.getUsername()), Placeholder.parsed("amount", amount.toPlainString())));
Placeholder.parsed("amount", amount.toPlainString())
)
);
} }
@Override @Override
public CommandNode<CommandSource> build() { public CommandNode<CommandSource> build() {
if (currency.fractionalDigits() > 0) { if (currency.fractionalDigits() > 0) {
return builder() return builder()
.requires((source) -> source.sender().eligible("lighteco.currency." + currency.getIdentifier() + ".command.set")) .requires((source) -> source.sender()
.then(RequiredArgumentBuilder.<CommandSource, String>argument("target", StringArgumentType.word()) .eligible("lighteco.currency." + currency.getIdentifier()
+ ".command.set"))
.then(RequiredArgumentBuilder.<CommandSource, String>argument(
"target", StringArgumentType.word())
.suggests(OfflineUserSuggestionProvider.create()) .suggests(OfflineUserSuggestionProvider.create())
.then(RequiredArgumentBuilder.<CommandSource, Double>argument("amount", DoubleArgumentType.doubleArg(1)) .then(RequiredArgumentBuilder.<CommandSource, Double>argument(
.requires((source) -> source.sender().eligible("lighteco.currency." + currency.getIdentifier() + ".command.set")) "amount", DoubleArgumentType.doubleArg(1))
.requires((source) -> source.sender()
.eligible("lighteco.currency."
+ currency.getIdentifier() + ".command.set"))
.executes(c -> { .executes(c -> {
execute(c); execute(c);
return SINGLE_SUCCESS; return SINGLE_SUCCESS;
}))) })))
.build(); .build();
} }
return builder() return builder()
.requires((source) -> source.sender().eligible("lighteco.currency." + currency.getIdentifier() + ".command.set")) .requires((source) -> source.sender()
.then(RequiredArgumentBuilder.<CommandSource, String>argument("target", StringArgumentType.word()) .eligible("lighteco.currency." + currency.getIdentifier() + ".command.set"))
.then(RequiredArgumentBuilder.<CommandSource, String>argument(
"target", StringArgumentType.word())
.suggests(OfflineUserSuggestionProvider.create()) .suggests(OfflineUserSuggestionProvider.create())
.then(RequiredArgumentBuilder.<CommandSource, Integer>argument("amount", IntegerArgumentType.integer(1)) .then(RequiredArgumentBuilder.<CommandSource, Integer>argument(
.requires((source) -> source.sender().eligible("lighteco.currency." + currency.getIdentifier() + ".command.set")) "amount", IntegerArgumentType.integer(1))
.requires((source) -> source.sender()
.eligible("lighteco.currency." + currency.getIdentifier()
+ ".command.set"))
.executes(c -> { .executes(c -> {
execute(c); execute(c);
return SINGLE_SUCCESS; return SINGLE_SUCCESS;

View file

@ -1,11 +1,16 @@
package dev.xhyrom.lighteco.common.commands; package dev.xhyrom.lighteco.common.commands;
import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
import static dev.xhyrom.lighteco.common.command.CommandHelper.*;
import com.mojang.brigadier.arguments.DoubleArgumentType; import com.mojang.brigadier.arguments.DoubleArgumentType;
import com.mojang.brigadier.arguments.IntegerArgumentType; import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.RequiredArgumentBuilder; import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.tree.CommandNode; import com.mojang.brigadier.tree.CommandNode;
import dev.xhyrom.lighteco.api.exception.CannotBeGreaterThan; import dev.xhyrom.lighteco.api.exception.CannotBeGreaterThan;
import dev.xhyrom.lighteco.common.command.CommandSource; import dev.xhyrom.lighteco.common.command.CommandSource;
import dev.xhyrom.lighteco.common.command.abstraction.Command; import dev.xhyrom.lighteco.common.command.abstraction.Command;
@ -14,16 +19,15 @@ import dev.xhyrom.lighteco.common.model.chat.CommandSender;
import dev.xhyrom.lighteco.common.model.currency.Currency; import dev.xhyrom.lighteco.common.model.currency.Currency;
import dev.xhyrom.lighteco.common.model.user.User; import dev.xhyrom.lighteco.common.model.user.User;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
import static dev.xhyrom.lighteco.common.command.CommandHelper.*;
public class TakeCommand extends Command { public class TakeCommand extends Command {
private static final MiniMessage miniMessage = MiniMessage.miniMessage(); private static final MiniMessage miniMessage = MiniMessage.miniMessage();
private final Currency currency; private final Currency currency;
@ -43,60 +47,66 @@ public class TakeCommand extends Command {
final CommandSender sender = context.getSource().sender(); final CommandSender sender = context.getSource().sender();
final User target = getUser(context); final User target = getUser(context);
if (target == null) if (target == null) return;
return;
BigDecimal amount = BigDecimal.valueOf(currency.fractionalDigits() > 0 BigDecimal amount = BigDecimal.valueOf(
? context.getArgument("amount", Double.class) currency.fractionalDigits() > 0
: context.getArgument("amount", Integer.class)); ? context.getArgument("amount", Double.class)
: context.getArgument("amount", Integer.class));
amount = amount.setScale(currency.fractionalDigits(), RoundingMode.DOWN); amount = amount.setScale(currency.fractionalDigits(), RoundingMode.DOWN);
try { try {
target.withdraw(currency, amount); target.withdraw(currency, amount);
} catch (CannotBeGreaterThan e) { } catch (CannotBeGreaterThan e) {
sender.sendMessage( sender.sendMessage(miniMessage.deserialize(
miniMessage.deserialize( getCurrencyMessageConfig(plugin, this.currency).cannotBeGreaterThan,
getCurrencyMessageConfig(plugin, this.currency).cannotBeGreaterThan, Placeholder.parsed("max", plugin.getConfig().maximumBalance.toPlainString())));
Placeholder.parsed("max", plugin.getConfig().maximumBalance.toPlainString())
)
);
return; return;
} }
sender.sendMessage( sender.sendMessage(miniMessage.deserialize(
miniMessage.deserialize( getCurrencyMessageConfig(plugin, this.currency).set,
getCurrencyMessageConfig(plugin, this.currency).set, Placeholder.parsed("currency", currency.getIdentifier()),
Placeholder.parsed("currency", currency.getIdentifier()), Placeholder.parsed("target", target.getUsername()),
Placeholder.parsed("target", target.getUsername()), Placeholder.parsed("amount", amount.toPlainString())));
Placeholder.parsed("amount", amount.toPlainString())
)
);
} }
@Override @Override
public CommandNode<CommandSource> build() { public CommandNode<CommandSource> build() {
if (currency.fractionalDigits() > 0) { if (currency.fractionalDigits() > 0) {
return builder() return builder()
.requires((source) -> source.sender().eligible("lighteco.currency." + currency.getIdentifier() + ".command.take")) .requires((source) -> source.sender()
.then(RequiredArgumentBuilder.<CommandSource, String>argument("target", StringArgumentType.word()) .eligible("lighteco.currency." + currency.getIdentifier()
+ ".command.take"))
.then(RequiredArgumentBuilder.<CommandSource, String>argument(
"target", StringArgumentType.word())
.suggests(OfflineUserSuggestionProvider.create()) .suggests(OfflineUserSuggestionProvider.create())
.then(RequiredArgumentBuilder.<CommandSource, Double>argument("amount", DoubleArgumentType.doubleArg(1)) .then(RequiredArgumentBuilder.<CommandSource, Double>argument(
.requires((source) -> source.sender().eligible("lighteco.currency." + currency.getIdentifier() + ".command.take")) "amount", DoubleArgumentType.doubleArg(1))
.requires((source) -> source.sender()
.eligible("lighteco.currency."
+ currency.getIdentifier() + ".command.take"))
.executes(c -> { .executes(c -> {
execute(c); execute(c);
return SINGLE_SUCCESS; return SINGLE_SUCCESS;
}))) })))
.build(); .build();
} }
return builder() return builder()
.requires((source) -> source.sender().eligible("lighteco.currency." + currency.getIdentifier() + ".command.take")) .requires((source) -> source.sender()
.then(RequiredArgumentBuilder.<CommandSource, String>argument("target", StringArgumentType.word()) .eligible(
"lighteco.currency." + currency.getIdentifier() + ".command.take"))
.then(RequiredArgumentBuilder.<CommandSource, String>argument(
"target", StringArgumentType.word())
.suggests(OfflineUserSuggestionProvider.create()) .suggests(OfflineUserSuggestionProvider.create())
.then(RequiredArgumentBuilder.<CommandSource, Integer>argument("amount", IntegerArgumentType.integer(1)) .then(RequiredArgumentBuilder.<CommandSource, Integer>argument(
.requires((source) -> source.sender().eligible("lighteco.currency." + currency.getIdentifier() + ".command.take")) "amount", IntegerArgumentType.integer(1))
.requires((source) -> source.sender()
.eligible("lighteco.currency." + currency.getIdentifier()
+ ".command.take"))
.executes(c -> { .executes(c -> {
execute(c); execute(c);
return SINGLE_SUCCESS; return SINGLE_SUCCESS;

View file

@ -4,6 +4,7 @@ import dev.xhyrom.lighteco.common.config.housekeeper.HousekeeperConfig;
import dev.xhyrom.lighteco.common.config.message.MessageConfig; import dev.xhyrom.lighteco.common.config.message.MessageConfig;
import dev.xhyrom.lighteco.common.config.messaging.MessagingConfig; import dev.xhyrom.lighteco.common.config.messaging.MessagingConfig;
import dev.xhyrom.lighteco.common.config.storage.StorageConfig; import dev.xhyrom.lighteco.common.config.storage.StorageConfig;
import eu.okaeri.configs.OkaeriConfig; import eu.okaeri.configs.OkaeriConfig;
import eu.okaeri.configs.annotation.Comment; import eu.okaeri.configs.annotation.Comment;
import eu.okaeri.configs.annotation.Header; import eu.okaeri.configs.annotation.Header;
@ -14,7 +15,8 @@ import java.math.BigDecimal;
@Header("") @Header("")
public class Config extends OkaeriConfig { public class Config extends OkaeriConfig {
@Comment("This property must be unique for each server.") @Comment("This property must be unique for each server.")
@Comment("If you have multiple servers, you must set this property to a different value for each server.") @Comment(
"If you have multiple servers, you must set this property to a different value for each server.")
@Comment("Used for local currencies.") @Comment("Used for local currencies.")
public String server = "none"; public String server = "none";
@ -28,7 +30,8 @@ public class Config extends OkaeriConfig {
public long saveInterval = 5L; public long saveInterval = 5L;
@Comment("Maximum allowed balance.") @Comment("Maximum allowed balance.")
@Comment("If you want to change this value, you must also change the data type in the database.") @Comment(
"If you want to change this value, you must also change the data type in the database.")
public BigDecimal maximumBalance = BigDecimal.valueOf(999999999999999.99); public BigDecimal maximumBalance = BigDecimal.valueOf(999999999999999.99);
@Comment("Messages") @Comment("Messages")

View file

@ -8,9 +8,11 @@ import java.util.concurrent.TimeUnit;
public class HousekeeperConfig extends OkaeriConfig { public class HousekeeperConfig extends OkaeriConfig {
@Comment("How long should the cache be kept after the last write") @Comment("How long should the cache be kept after the last write")
public int expireAfterWrite = 300; public int expireAfterWrite = 300;
public TimeUnit expireAfterWriteUnit = TimeUnit.SECONDS; public TimeUnit expireAfterWriteUnit = TimeUnit.SECONDS;
@Comment("How often should housekeeper run") @Comment("How often should housekeeper run")
public int runInterval = 60; public int runInterval = 60;
public TimeUnit runIntervalUnit = TimeUnit.SECONDS; public TimeUnit runIntervalUnit = TimeUnit.SECONDS;
} }

View file

@ -4,18 +4,28 @@ import eu.okaeri.configs.OkaeriConfig;
import eu.okaeri.configs.annotation.Variable; import eu.okaeri.configs.annotation.Variable;
public class CurrencyMessageConfig extends OkaeriConfig { public class CurrencyMessageConfig extends OkaeriConfig {
public String balance = "<currency> <dark_gray>| <gray>Your balance: <yellow><balance> </yellow></gray>"; public String balance =
"<currency> <dark_gray>| <gray>Your balance: <yellow><balance> </yellow></gray>";
@Variable("balance-others") @Variable("balance-others")
public String balanceOthers = "<currency> <dark_gray>| <gray>Balance of <yellow><target> <dark_gray>| <gray><yellow><balance> </yellow></gray>"; public String balanceOthers =
"<currency> <dark_gray>| <gray>Balance of <yellow><target> <dark_gray>| <gray><yellow><balance> </yellow></gray>";
public String set = "<currency> <dark_gray>| <gray>Set balance of <gold><target> <yellow>to <gold><amount>"; public String set =
public String give = "<currency> <dark_gray>| <gray>Gave <gold><target> <gold><amount> <dark_gray>| <gold><balance>"; "<currency> <dark_gray>| <gray>Set balance of <gold><target> <yellow>to <gold><amount>";
public String take = "<currency> <dark_gray>| <gray>Took <gold><amount> <yellow>from <gold><target>"; public String give =
"<currency> <dark_gray>| <gray>Gave <gold><target> <gold><amount> <dark_gray>| <gold><balance>";
public String take =
"<currency> <dark_gray>| <gray>Took <gold><amount> <yellow>from <gold><target>";
public String pay = "<currency> <dark_gray>| <gray>Paid <gold><amount> <yellow>to <gold><target>"; public String pay =
public String payWithTax = "<currency> <dark_gray>| <gray>Paid <gold><amount> <yellow>to <gold><target> <dark_gray>(<gold><taxed_amount> <yellow>after tax<dark_gray>)"; "<currency> <dark_gray>| <gray>Paid <gold><amount> <yellow>to <gold><target>";
public String payReceived = "<currency> <dark_gray>| <gray>Received <gold><amount> <yellow>from <gold><sender>"; public String payWithTax =
public String payReceivedWithTax = "<currency> <dark_gray>| <gray>Received <gold><amount> <yellow>from <gold><sender> <dark_gray>(<gold><taxed_amount> <yellow>after tax<dark_gray>)"; "<currency> <dark_gray>| <gray>Paid <gold><amount> <yellow>to <gold><target> <dark_gray>(<gold><taxed_amount> <yellow>after tax<dark_gray>)";
public String payReceived =
"<currency> <dark_gray>| <gray>Received <gold><amount> <yellow>from <gold><sender>";
public String payReceivedWithTax =
"<currency> <dark_gray>| <gray>Received <gold><amount> <yellow>from <gold><sender> <dark_gray>(<gold><taxed_amount> <yellow>after tax<dark_gray>)";
public String notEnoughMoney = "<red>You don't have enough money!"; public String notEnoughMoney = "<red>You don't have enough money!";
public String cannotPaySelf = "<red>You cannot pay yourself!"; public String cannotPaySelf = "<red>You cannot pay yourself!";

View file

@ -6,7 +6,8 @@ import java.util.Collections;
import java.util.Map; import java.util.Map;
public class MessageConfig extends OkaeriConfig { public class MessageConfig extends OkaeriConfig {
public Map<String, CurrencyMessageConfig> currency = Collections.singletonMap("default", new CurrencyMessageConfig()); public Map<String, CurrencyMessageConfig> currency =
Collections.singletonMap("default", new CurrencyMessageConfig());
public String wait = "<red>Please wait a moment before using this command again."; public String wait = "<red>Please wait a moment before using this command again.";
public String userNotFound = "<red>User <username> not found."; public String userNotFound = "<red>User <username> not found.";

View file

@ -1,6 +1,7 @@
package dev.xhyrom.lighteco.common.config.messaging; package dev.xhyrom.lighteco.common.config.messaging;
import dev.xhyrom.lighteco.common.messaging.MessagingType; import dev.xhyrom.lighteco.common.messaging.MessagingType;
import eu.okaeri.configs.OkaeriConfig; import eu.okaeri.configs.OkaeriConfig;
import eu.okaeri.configs.annotation.Comment; import eu.okaeri.configs.annotation.Comment;

View file

@ -9,6 +9,7 @@ public class MessagingDataConfig extends OkaeriConfig {
@Comment("Credentials for connecting to the messaging service.") @Comment("Credentials for connecting to the messaging service.")
public String username = "root"; public String username = "root";
public String password = "password"; public String password = "password";
@Comment("Whether to use SSL to connect to the messaging service.") @Comment("Whether to use SSL to connect to the messaging service.")

View file

@ -1,6 +1,7 @@
package dev.xhyrom.lighteco.common.config.storage; package dev.xhyrom.lighteco.common.config.storage;
import dev.xhyrom.lighteco.common.storage.StorageType; import dev.xhyrom.lighteco.common.storage.StorageType;
import eu.okaeri.configs.OkaeriConfig; import eu.okaeri.configs.OkaeriConfig;
import eu.okaeri.configs.annotation.Comment; import eu.okaeri.configs.annotation.Comment;

View file

@ -12,6 +12,7 @@ public class StorageDataConfig extends OkaeriConfig {
@Comment("Credentials for connecting to the database.") @Comment("Credentials for connecting to the database.")
public String username = "root"; public String username = "root";
public String password = "password"; public String password = "password";
@Comment("Maximum number of connections in the pool.") @Comment("Maximum number of connections in the pool.")

View file

@ -1,7 +1,9 @@
package dev.xhyrom.lighteco.common.dependencies; package dev.xhyrom.lighteco.common.dependencies;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import dev.xhyrom.lighteco.common.dependencies.relocation.Relocation; import dev.xhyrom.lighteco.common.dependencies.relocation.Relocation;
import lombok.Getter; import lombok.Getter;
import java.util.List; import java.util.List;
@ -12,82 +14,40 @@ public enum Dependency {
* Somewhere we use brackets instad of dots, so we need to rewrite them * Somewhere we use brackets instad of dots, so we need to rewrite them
* This is because gradle's shadow plugin relocates using replacing full paths (dots) * This is because gradle's shadow plugin relocates using replacing full paths (dots)
*/ */
ASM("org.ow2.asm", "asm", "9.1"),
ASM( ASM_COMMONS("org.ow2.asm", "asm-commons", "9.1"),
"org.ow2.asm", JAR_RELOCATOR("me.lucko", "jar-relocator", "1.7"),
"asm", HIKARI("com{}zaxxer", "HikariCP", "5.0.1", Relocation.of("hikari", "com{}zaxxer{}hikari")),
"9.1" H2_DRIVER("com.h2database", "h2", "2.1.214"),
), SQLITE_DRIVER("org.xerial", "sqlite-jdbc", "3.28.0"),
ASM_COMMONS(
"org.ow2.asm",
"asm-commons",
"9.1"
),
JAR_RELOCATOR(
"me.lucko",
"jar-relocator",
"1.7"
),
HIKARI(
"com{}zaxxer",
"HikariCP",
"5.0.1",
Relocation.of("hikari", "com{}zaxxer{}hikari")
),
H2_DRIVER(
"com.h2database",
"h2",
"2.1.214"
),
SQLITE_DRIVER(
"org.xerial",
"sqlite-jdbc",
"3.28.0"
),
MARIADB_DRIVER( MARIADB_DRIVER(
"org{}mariadb{}jdbc", "org{}mariadb{}jdbc",
"mariadb-java-client", "mariadb-java-client",
"3.1.3", "3.1.3",
Relocation.of("mariadb", "org{}mariadb{}jdbc") Relocation.of("mariadb", "org{}mariadb{}jdbc")),
), MYSQL_DRIVER("mysql", "mysql-connector-java", "8.0.23", Relocation.of("mysql", "com{}mysql")),
MYSQL_DRIVER(
"mysql",
"mysql-connector-java",
"8.0.23",
Relocation.of("mysql", "com{}mysql")
),
POSTGRESQL_DRIVER( POSTGRESQL_DRIVER(
"org{}postgresql", "org{}postgresql",
"postgresql", "postgresql",
"42.6.0", "42.6.0",
Relocation.of("postgresql", "org{}postgresql") Relocation.of("postgresql", "org{}postgresql")),
),
JEDIS( JEDIS(
"redis.clients", "redis.clients",
"jedis", "jedis",
"5.1.0", "5.1.0",
Relocation.of("jedis", "redis{}clients{}jedis"), Relocation.of("jedis", "redis{}clients{}jedis"),
Relocation.of("commonspool2", "org{}apache{}commons{}pool2") Relocation.of("commonspool2", "org{}apache{}commons{}pool2")),
), SLF4J_SIMPLE("org.slf4j", "slf4j-simple", "1.7.30"),
SLF4J_SIMPLE( SLF4J_API("org.slf4j", "slf4j-api", "1.7.30"),
"org.slf4j",
"slf4j-simple",
"1.7.30"
),
SLF4J_API(
"org.slf4j",
"slf4j-api",
"1.7.30"
),
COMMONS_POOL_2( COMMONS_POOL_2(
"org.apache.commons", "org.apache.commons",
"commons-pool2", "commons-pool2",
"2.9.0", "2.9.0",
Relocation.of("commonspool2", "org{}apache{}commons{}pool2") Relocation.of("commonspool2", "org{}apache{}commons{}pool2"));
);
private final String fullPath; private final String fullPath;
private final String version; private final String version;
@Getter @Getter
private final List<Relocation> relocations; private final List<Relocation> relocations;
@ -98,13 +58,13 @@ public enum Dependency {
} }
Dependency(String groupId, String artifactId, String version, Relocation... relocations) { Dependency(String groupId, String artifactId, String version, Relocation... relocations) {
this.fullPath = String.format(MAVEN_FORMAT, this.fullPath = String.format(
MAVEN_FORMAT,
rewriteEscape(groupId).replace('.', '/'), rewriteEscape(groupId).replace('.', '/'),
rewriteEscape(artifactId), rewriteEscape(artifactId),
version, version,
rewriteEscape(artifactId), rewriteEscape(artifactId),
version version);
);
this.version = version; this.version = version;
this.relocations = ImmutableList.copyOf(relocations); this.relocations = ImmutableList.copyOf(relocations);

View file

@ -9,6 +9,7 @@ public interface DependencyManager extends AutoCloseable {
void loadDependencies(Set<Dependency> dependencies); void loadDependencies(Set<Dependency> dependencies);
void loadStorageDependencies(Set<StorageType> types); void loadStorageDependencies(Set<StorageType> types);
void loadMessagingDependencies(Set<MessagingType> types); void loadMessagingDependencies(Set<MessagingType> types);
ClassLoader obtainClassLoaderWith(Set<Dependency> dependencies); ClassLoader obtainClassLoaderWith(Set<Dependency> dependencies);

View file

@ -2,6 +2,7 @@ package dev.xhyrom.lighteco.common.dependencies;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.io.MoreFiles; import com.google.common.io.MoreFiles;
import dev.xhyrom.lighteco.common.config.Config; import dev.xhyrom.lighteco.common.config.Config;
import dev.xhyrom.lighteco.common.dependencies.relocation.Relocation; import dev.xhyrom.lighteco.common.dependencies.relocation.Relocation;
import dev.xhyrom.lighteco.common.dependencies.relocation.RelocationHandler; import dev.xhyrom.lighteco.common.dependencies.relocation.RelocationHandler;
@ -10,6 +11,7 @@ import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import dev.xhyrom.lighteco.common.plugin.logger.PluginLogger; import dev.xhyrom.lighteco.common.plugin.logger.PluginLogger;
import dev.xhyrom.lighteco.common.storage.StorageType; import dev.xhyrom.lighteco.common.storage.StorageType;
import dev.xhyrom.lighteco.common.util.URLClassLoaderAccess; import dev.xhyrom.lighteco.common.util.URLClassLoaderAccess;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import java.io.IOException; import java.io.IOException;
@ -35,7 +37,8 @@ public class DependencyManagerImpl implements DependencyManager {
this.logger = plugin.getBootstrap().getLogger(); this.logger = plugin.getBootstrap().getLogger();
this.registry = new DependencyRegistry(); this.registry = new DependencyRegistry();
this.cacheDirectory = setupCacheDirectory(plugin); this.cacheDirectory = setupCacheDirectory(plugin);
this.classLoader = URLClassLoaderAccess.create((URLClassLoader) plugin.getBootstrap().getClass().getClassLoader()); this.classLoader = URLClassLoaderAccess.create(
(URLClassLoader) plugin.getBootstrap().getClass().getClassLoader());
} }
private synchronized RelocationHandler getRelocationHandler() { private synchronized RelocationHandler getRelocationHandler() {
@ -48,29 +51,25 @@ public class DependencyManagerImpl implements DependencyManager {
@Override @Override
public void loadDependencies(Set<Dependency> dependencies) { public void loadDependencies(Set<Dependency> dependencies) {
if (this.config.debug) if (this.config.debug) this.logger.info("Loading dependencies: " + dependencies);
this.logger.info("Loading dependencies: " + dependencies);
for (Dependency dependency : dependencies) { for (Dependency dependency : dependencies) {
if (this.loaded.containsKey(dependency)) { if (this.loaded.containsKey(dependency)) {
continue; continue;
} }
if (this.config.debug) if (this.config.debug) this.logger.info("Loading dependency " + dependency);
this.logger.info("Loading dependency " + dependency);
try { try {
loadDependency(dependency); loadDependency(dependency);
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException("Failed to load dependency " + dependency, e); throw new RuntimeException("Failed to load dependency " + dependency, e);
} finally { } finally {
if (this.config.debug) if (this.config.debug) this.logger.info("Loaded dependency " + dependency);
this.logger.info("Loaded dependency " + dependency);
} }
} }
if (this.config.debug) if (this.config.debug) this.logger.info("Loaded dependencies: " + dependencies);
this.logger.info("Loaded dependencies: " + dependencies);
} }
private void loadDependency(Dependency dependency) throws Exception { private void loadDependency(Dependency dependency) throws Exception {

View file

@ -2,6 +2,7 @@ package dev.xhyrom.lighteco.common.dependencies;
import com.google.common.collect.ImmutableSetMultimap; import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.SetMultimap; import com.google.common.collect.SetMultimap;
import dev.xhyrom.lighteco.common.messaging.MessagingType; import dev.xhyrom.lighteco.common.messaging.MessagingType;
import dev.xhyrom.lighteco.common.storage.StorageType; import dev.xhyrom.lighteco.common.storage.StorageType;
@ -9,17 +10,24 @@ import java.util.LinkedHashSet;
import java.util.Set; import java.util.Set;
public class DependencyRegistry { public class DependencyRegistry {
private static final SetMultimap<StorageType, Dependency> STORAGE_DEPENDENCIES = ImmutableSetMultimap.<StorageType, Dependency>builder() private static final SetMultimap<StorageType, Dependency> STORAGE_DEPENDENCIES =
.putAll(StorageType.SQLITE, Dependency.SQLITE_DRIVER) ImmutableSetMultimap.<StorageType, Dependency>builder()
.putAll(StorageType.H2, Dependency.H2_DRIVER) .putAll(StorageType.SQLITE, Dependency.SQLITE_DRIVER)
.putAll(StorageType.MYSQL, Dependency.MYSQL_DRIVER, Dependency.HIKARI) .putAll(StorageType.H2, Dependency.H2_DRIVER)
.putAll(StorageType.MARIADB, Dependency.MARIADB_DRIVER, Dependency.HIKARI) .putAll(StorageType.MYSQL, Dependency.MYSQL_DRIVER, Dependency.HIKARI)
.putAll(StorageType.POSTGRESQL, Dependency.POSTGRESQL_DRIVER, Dependency.HIKARI) .putAll(StorageType.MARIADB, Dependency.MARIADB_DRIVER, Dependency.HIKARI)
.build(); .putAll(StorageType.POSTGRESQL, Dependency.POSTGRESQL_DRIVER, Dependency.HIKARI)
.build();
private static final SetMultimap<MessagingType, Dependency> MESSAGING_DEPENDENCIES = ImmutableSetMultimap.<MessagingType, Dependency>builder() private static final SetMultimap<MessagingType, Dependency> MESSAGING_DEPENDENCIES =
.putAll(MessagingType.REDIS, Dependency.COMMONS_POOL_2, Dependency.JEDIS, Dependency.SLF4J_API, Dependency.SLF4J_SIMPLE) ImmutableSetMultimap.<MessagingType, Dependency>builder()
.build(); .putAll(
MessagingType.REDIS,
Dependency.COMMONS_POOL_2,
Dependency.JEDIS,
Dependency.SLF4J_API,
Dependency.SLF4J_SIMPLE)
.build();
public Set<Dependency> resolveStorageDependencies(Set<StorageType> types) { public Set<Dependency> resolveStorageDependencies(Set<StorageType> types) {
Set<Dependency> dependencies = new LinkedHashSet<>(); Set<Dependency> dependencies = new LinkedHashSet<>();

View file

@ -11,5 +11,4 @@ public class IsolatedClassLoader extends URLClassLoader {
public IsolatedClassLoader(URL[] urls) { public IsolatedClassLoader(URL[] urls) {
super(urls, ClassLoader.getSystemClassLoader().getParent()); super(urls, ClassLoader.getSystemClassLoader().getParent());
} }
} }

View file

@ -17,5 +17,4 @@ public class Relocation {
this.pattern = pattern; this.pattern = pattern;
this.relocatedPattern = relocatedPattern; this.relocatedPattern = relocatedPattern;
} }
} }

View file

@ -12,7 +12,8 @@ import java.nio.file.Path;
import java.util.*; import java.util.*;
public class RelocationHandler { public class RelocationHandler {
public static final Set<Dependency> DEPENDENCIES = EnumSet.of(Dependency.ASM, Dependency.ASM_COMMONS, Dependency.JAR_RELOCATOR); public static final Set<Dependency> DEPENDENCIES =
EnumSet.of(Dependency.ASM, Dependency.ASM_COMMONS, Dependency.JAR_RELOCATOR);
private static final String JAR_RELOCATOR_CLASS = "me.lucko.jarrelocator.JarRelocator"; private static final String JAR_RELOCATOR_CLASS = "me.lucko.jarrelocator.JarRelocator";
private static final String JAR_RELOCATOR_RUN_METHOD = "run"; private static final String JAR_RELOCATOR_RUN_METHOD = "run";
@ -31,10 +32,12 @@ public class RelocationHandler {
Class<?> jarRelocatorClass = classLoader.loadClass(JAR_RELOCATOR_CLASS); Class<?> jarRelocatorClass = classLoader.loadClass(JAR_RELOCATOR_CLASS);
// prepare the reflected constructor & method instances // prepare the reflected constructor & method instances
this.jarRelocatorConstructor = jarRelocatorClass.getDeclaredConstructor(File.class, File.class, Map.class); this.jarRelocatorConstructor =
jarRelocatorClass.getDeclaredConstructor(File.class, File.class, Map.class);
this.jarRelocatorConstructor.setAccessible(true); this.jarRelocatorConstructor.setAccessible(true);
this.jarRelocatorRunMethod = jarRelocatorClass.getDeclaredMethod(JAR_RELOCATOR_RUN_METHOD); this.jarRelocatorRunMethod =
jarRelocatorClass.getDeclaredMethod(JAR_RELOCATOR_RUN_METHOD);
this.jarRelocatorRunMethod.setAccessible(true); this.jarRelocatorRunMethod.setAccessible(true);
} catch (Exception e) { } catch (Exception e) {
try { try {
@ -56,8 +59,8 @@ public class RelocationHandler {
} }
// create and invoke a new relocator // create and invoke a new relocator
Object relocator = this.jarRelocatorConstructor.newInstance(input.toFile(), output.toFile(), mappings); Object relocator =
this.jarRelocatorConstructor.newInstance(input.toFile(), output.toFile(), mappings);
this.jarRelocatorRunMethod.invoke(relocator); this.jarRelocatorRunMethod.invoke(relocator);
} }
} }

View file

@ -6,6 +6,7 @@ public interface Manager<I, T> {
T apply(I identifier); T apply(I identifier);
Collection<I> keys(); Collection<I> keys();
Collection<T> values(); Collection<T> values();
T getOrMake(I identifier); T getOrMake(I identifier);

View file

@ -2,6 +2,7 @@ package dev.xhyrom.lighteco.common.manager.currency;
import dev.xhyrom.lighteco.common.manager.Manager; import dev.xhyrom.lighteco.common.manager.Manager;
import dev.xhyrom.lighteco.common.model.currency.Currency; import dev.xhyrom.lighteco.common.model.currency.Currency;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.Collection; import java.util.Collection;

View file

@ -3,11 +3,13 @@ package dev.xhyrom.lighteco.common.manager.currency;
import dev.xhyrom.lighteco.common.manager.SingleManager; import dev.xhyrom.lighteco.common.manager.SingleManager;
import dev.xhyrom.lighteco.common.model.currency.Currency; import dev.xhyrom.lighteco.common.model.currency.Currency;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.Collection; import java.util.Collection;
public class StandardCurrencyManager extends SingleManager<String, Currency> implements CurrencyManager { public class StandardCurrencyManager extends SingleManager<String, Currency>
implements CurrencyManager {
private final LightEcoPlugin plugin; private final LightEcoPlugin plugin;
public StandardCurrencyManager(LightEcoPlugin plugin) { public StandardCurrencyManager(LightEcoPlugin plugin) {
@ -32,10 +34,14 @@ public class StandardCurrencyManager extends SingleManager<String, Currency> imp
@Override @Override
public void registerCurrency(@NonNull Currency currency) { public void registerCurrency(@NonNull Currency currency) {
if (this.isLoaded(currency.getIdentifier())) if (this.isLoaded(currency.getIdentifier()))
throw new IllegalArgumentException("Currency with identifier " + currency.getIdentifier() + " already registered"); throw new IllegalArgumentException(
"Currency with identifier " + currency.getIdentifier() + " already registered");
if (this.plugin.getConfig().debug) if (this.plugin.getConfig().debug)
this.plugin.getBootstrap().getLogger().info("Registering currency " + currency.getIdentifier()); this.plugin
.getBootstrap()
.getLogger()
.info("Registering currency " + currency.getIdentifier());
this.plugin.getStorage().registerCurrencySync(currency.getProxy()); this.plugin.getStorage().registerCurrencySync(currency.getProxy());
this.map.put(currency.getIdentifier(), currency); this.map.put(currency.getIdentifier(), currency);

View file

@ -3,6 +3,7 @@ package dev.xhyrom.lighteco.common.manager.user;
import dev.xhyrom.lighteco.common.manager.ConcurrentManager; import dev.xhyrom.lighteco.common.manager.ConcurrentManager;
import dev.xhyrom.lighteco.common.model.user.User; import dev.xhyrom.lighteco.common.model.user.User;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import lombok.Getter; import lombok.Getter;
import java.util.Arrays; import java.util.Arrays;
@ -11,21 +12,26 @@ import java.util.concurrent.CompletableFuture;
public class StandardUserManager extends ConcurrentManager<UUID, User> implements UserManager { public class StandardUserManager extends ConcurrentManager<UUID, User> implements UserManager {
private final LightEcoPlugin plugin; private final LightEcoPlugin plugin;
@Getter @Getter
private final UserHousekeeper housekeeper; private final UserHousekeeper housekeeper;
public StandardUserManager(LightEcoPlugin plugin) { public StandardUserManager(LightEcoPlugin plugin) {
this.plugin = plugin; this.plugin = plugin;
this.housekeeper = new UserHousekeeper(plugin, this, UserHousekeeper.timeoutSettings( this.housekeeper = new UserHousekeeper(
this.plugin.getConfig().housekeeper.expireAfterWrite, plugin,
this.plugin.getConfig().housekeeper.expireAfterWriteUnit this,
)); UserHousekeeper.timeoutSettings(
this.plugin.getConfig().housekeeper.expireAfterWrite,
this.plugin.getConfig().housekeeper.expireAfterWriteUnit));
this.plugin.getBootstrap().getScheduler().asyncRepeating( this.plugin
this.housekeeper, .getBootstrap()
this.plugin.getConfig().housekeeper.runInterval, .getScheduler()
this.plugin.getConfig().housekeeper.runIntervalUnit .asyncRepeating(
); this.housekeeper,
this.plugin.getConfig().housekeeper.runInterval,
this.plugin.getConfig().housekeeper.runIntervalUnit);
} }
@Override @Override
@ -49,15 +55,15 @@ public class StandardUserManager extends ConcurrentManager<UUID, User> implement
@Override @Override
public CompletableFuture<Void> saveUser(User user) { public CompletableFuture<Void> saveUser(User user) {
return this.plugin.getStorage().saveUser(user.getProxy()); return this.plugin.getStorage().saveUser(user.getProxy());
} }
@Override @Override
public CompletableFuture<Void> saveUsers(User... users) { public CompletableFuture<Void> saveUsers(User... users) {
return this.plugin.getStorage().saveUsers( return this.plugin
Arrays.stream(users) .getStorage()
.saveUsers(Arrays.stream(users)
.map(User::getProxy) .map(User::getProxy)
.toArray(dev.xhyrom.lighteco.api.model.user.User[]::new) .toArray(dev.xhyrom.lighteco.api.model.user.User[]::new));
);
} }
} }

View file

@ -13,7 +13,8 @@ public class UserHousekeeper implements Runnable {
private final ExpiringSet<UUID> recentlyUsed; private final ExpiringSet<UUID> recentlyUsed;
public UserHousekeeper(LightEcoPlugin plugin, UserManager userManager, TimeoutSettings timeoutSettings) { public UserHousekeeper(
LightEcoPlugin plugin, UserManager userManager, TimeoutSettings timeoutSettings) {
this.plugin = plugin; this.plugin = plugin;
this.userManager = userManager; this.userManager = userManager;
this.recentlyUsed = new ExpiringSet<>(timeoutSettings.duration, timeoutSettings.unit); this.recentlyUsed = new ExpiringSet<>(timeoutSettings.duration, timeoutSettings.unit);
@ -41,8 +42,7 @@ public class UserHousekeeper implements Runnable {
} }
// If the user is dirty (has unsaved changes), don't unload // If the user is dirty (has unsaved changes), don't unload
if (user.isDirty()) if (user.isDirty()) return;
return;
if (this.plugin.getConfig().debug) { if (this.plugin.getConfig().debug) {
this.plugin.getBootstrap().getLogger().info("Unloading data for " + uuid); this.plugin.getBootstrap().getLogger().info("Unloading data for " + uuid);

View file

@ -10,8 +10,10 @@ public interface UserManager extends Manager<UUID, User> {
UserHousekeeper getHousekeeper(); UserHousekeeper getHousekeeper();
CompletableFuture<Void> saveUser(User user); CompletableFuture<Void> saveUser(User user);
CompletableFuture<Void> saveUsers(User... users); CompletableFuture<Void> saveUsers(User... users);
CompletableFuture<User> loadUser(UUID uniqueId); CompletableFuture<User> loadUser(UUID uniqueId);
CompletableFuture<User> loadUser(UUID uniqueId, String username); CompletableFuture<User> loadUser(UUID uniqueId, String username);
} }

View file

@ -3,6 +3,7 @@ package dev.xhyrom.lighteco.common.messaging;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive; import com.google.gson.JsonPrimitive;
import dev.xhyrom.lighteco.api.messenger.IncomingMessageConsumer; import dev.xhyrom.lighteco.api.messenger.IncomingMessageConsumer;
import dev.xhyrom.lighteco.api.messenger.Messenger; import dev.xhyrom.lighteco.api.messenger.Messenger;
import dev.xhyrom.lighteco.api.messenger.MessengerProvider; import dev.xhyrom.lighteco.api.messenger.MessengerProvider;
@ -15,7 +16,9 @@ import dev.xhyrom.lighteco.common.model.currency.Currency;
import dev.xhyrom.lighteco.common.model.user.User; import dev.xhyrom.lighteco.common.model.user.User;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import dev.xhyrom.lighteco.common.util.gson.GsonProvider; import dev.xhyrom.lighteco.common.util.gson.GsonProvider;
import lombok.Getter; import lombok.Getter;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
@ -25,6 +28,7 @@ import java.util.concurrent.TimeUnit;
public class LightEcoMessagingService implements InternalMessagingService, IncomingMessageConsumer { public class LightEcoMessagingService implements InternalMessagingService, IncomingMessageConsumer {
@Getter @Getter
private final LightEcoPlugin plugin; private final LightEcoPlugin plugin;
private final ExpiringSet<UUID> receivedMessages; private final ExpiringSet<UUID> receivedMessages;
private final Messenger messenger; private final Messenger messenger;
@ -47,12 +51,18 @@ public class LightEcoMessagingService implements InternalMessagingService, Incom
@Override @Override
public void pushUserUpdate(User user, Currency currency) { public void pushUserUpdate(User user, Currency currency) {
this.plugin.getBootstrap().getScheduler().async().execute(() -> this.plugin
this.messenger.sendOutgoingMessage( .getBootstrap()
new UserUpdateMessageImpl(generateMessageId(), user.getUniqueId(), currency.getIdentifier(), user.getBalance(currency)), .getScheduler()
currency.getType() == dev.xhyrom.lighteco.api.model.currency.Currency.Type.GLOBAL .async()
) .execute(() -> this.messenger.sendOutgoingMessage(
); new UserUpdateMessageImpl(
generateMessageId(),
user.getUniqueId(),
currency.getIdentifier(),
user.getBalance(currency)),
currency.getType()
== dev.xhyrom.lighteco.api.model.currency.Currency.Type.GLOBAL));
} }
public static @NonNull String serialize(MessageType type, UUID id, JsonElement content) { public static @NonNull String serialize(MessageType type, UUID id, JsonElement content) {
@ -79,7 +89,10 @@ public class LightEcoMessagingService implements InternalMessagingService, Incom
try { try {
deserializeAndConsumeRawIncomingMessage(message); deserializeAndConsumeRawIncomingMessage(message);
} catch (Exception e) { } catch (Exception e) {
this.plugin.getBootstrap().getLogger().warn("Failed to deserialize incoming message: " + message, e); this.plugin
.getBootstrap()
.getLogger()
.warn("Failed to deserialize incoming message: " + message, e);
} }
} }
@ -121,12 +134,16 @@ public class LightEcoMessagingService implements InternalMessagingService, Incom
private void processIncomingMessage(Message message) { private void processIncomingMessage(Message message) {
if (message instanceof UserUpdateMessage userUpdateMessage) { if (message instanceof UserUpdateMessage userUpdateMessage) {
this.plugin.getBootstrap().getScheduler().async().execute(() -> { this.plugin.getBootstrap().getScheduler().async().execute(() -> {
User user = this.plugin.getUserManager().getIfLoaded(userUpdateMessage.getUserUniqueId()); User user = this.plugin
.getUserManager()
.getIfLoaded(userUpdateMessage.getUserUniqueId());
if (user == null) { if (user == null) {
return; return;
} }
Currency currency = this.plugin.getCurrencyManager().getIfLoaded(userUpdateMessage.getCurrencyIdentifier()); Currency currency = this.plugin
.getCurrencyManager()
.getIfLoaded(userUpdateMessage.getCurrencyIdentifier());
if (currency == null) { if (currency == null) {
return; return;
} }
@ -134,7 +151,8 @@ public class LightEcoMessagingService implements InternalMessagingService, Incom
user.setBalance(currency, userUpdateMessage.getNewBalance(), false, false); user.setBalance(currency, userUpdateMessage.getNewBalance(), false, false);
}); });
} else { } else {
throw new IllegalStateException("Unknown message type: " + message.getClass().getName()); throw new IllegalStateException(
"Unknown message type: " + message.getClass().getName());
} }
} }

View file

@ -2,6 +2,7 @@ package dev.xhyrom.lighteco.common.messaging.message;
import dev.xhyrom.lighteco.api.messenger.message.Message; import dev.xhyrom.lighteco.api.messenger.message.Message;
import dev.xhyrom.lighteco.api.messenger.message.OutgoingMessage; import dev.xhyrom.lighteco.api.messenger.message.OutgoingMessage;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.UUID; import java.util.UUID;

View file

@ -3,9 +3,12 @@ package dev.xhyrom.lighteco.common.messaging.message;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive; import com.google.gson.JsonPrimitive;
import dev.xhyrom.lighteco.api.messenger.message.type.UserUpdateMessage; import dev.xhyrom.lighteco.api.messenger.message.type.UserUpdateMessage;
import dev.xhyrom.lighteco.common.messaging.LightEcoMessagingService; import dev.xhyrom.lighteco.common.messaging.LightEcoMessagingService;
import lombok.Getter; import lombok.Getter;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -16,8 +19,10 @@ public class UserUpdateMessageImpl extends AbstractMessage implements UserUpdate
@Getter @Getter
private final UUID userUniqueId; private final UUID userUniqueId;
@Getter @Getter
private final String currencyIdentifier; private final String currencyIdentifier;
@Getter @Getter
private final BigDecimal newBalance; private final BigDecimal newBalance;
@ -30,7 +35,8 @@ public class UserUpdateMessageImpl extends AbstractMessage implements UserUpdate
return new UserUpdateMessageImpl(id, userUniqueId, currencyIdentifier, newBalance); return new UserUpdateMessageImpl(id, userUniqueId, currencyIdentifier, newBalance);
} }
public UserUpdateMessageImpl(UUID id, UUID userUniqueId, String currencyIdentifier, BigDecimal newBalance) { public UserUpdateMessageImpl(
UUID id, UUID userUniqueId, String currencyIdentifier, BigDecimal newBalance) {
super(id); super(id);
this.userUniqueId = userUniqueId; this.userUniqueId = userUniqueId;
this.currencyIdentifier = currencyIdentifier; this.currencyIdentifier = currencyIdentifier;

View file

@ -4,13 +4,17 @@ import dev.xhyrom.lighteco.api.messenger.IncomingMessageConsumer;
import dev.xhyrom.lighteco.api.messenger.Messenger; import dev.xhyrom.lighteco.api.messenger.Messenger;
import dev.xhyrom.lighteco.api.messenger.message.OutgoingMessage; import dev.xhyrom.lighteco.api.messenger.message.OutgoingMessage;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import lombok.Getter; import lombok.Getter;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import redis.clients.jedis.*; import redis.clients.jedis.*;
public class RedisMessenger implements Messenger { public class RedisMessenger implements Messenger {
private static final String CHANNEL = "lighteco:{}:messages"; private static final String CHANNEL = "lighteco:{}:messages";
@Getter @Getter
private final String[] channels; private final String[] channels;
@ -25,16 +29,13 @@ public class RedisMessenger implements Messenger {
this.consumer = consumer; this.consumer = consumer;
this.channels = new String[] { this.channels = new String[] {
CHANNEL.replace("{}:", ""), CHANNEL.replace("{}:", ""), CHANNEL.replace("{}", this.plugin.getConfig().server)
CHANNEL.replace("{}", this.plugin.getConfig().server)
}; };
} }
public void init(@Nullable String address, @Nullable String username, String password, boolean ssl) { public void init(
this.init(new JedisPooled( @Nullable String address, @Nullable String username, String password, boolean ssl) {
parseAddress(address), this.init(new JedisPooled(parseAddress(address), jedisConfig(username, password, ssl)));
jedisConfig(username, password, ssl)
));
} }
private void init(UnifiedJedis jedis) { private void init(UnifiedJedis jedis) {
@ -46,7 +47,8 @@ public class RedisMessenger implements Messenger {
}); });
} }
private static JedisClientConfig jedisConfig(@Nullable String username, @Nullable String password, boolean ssl) { private static JedisClientConfig jedisConfig(
@Nullable String username, @Nullable String password, boolean ssl) {
return DefaultJedisClientConfig.builder() return DefaultJedisClientConfig.builder()
.user(username) .user(username)
.password(password) .password(password)
@ -58,7 +60,8 @@ public class RedisMessenger implements Messenger {
private static HostAndPort parseAddress(String address) { private static HostAndPort parseAddress(String address) {
String[] addressSplit = address.split(":"); String[] addressSplit = address.split(":");
String host = addressSplit[0]; String host = addressSplit[0];
int port = addressSplit.length > 1 ? Integer.parseInt(addressSplit[1]) : Protocol.DEFAULT_PORT; int port =
addressSplit.length > 1 ? Integer.parseInt(addressSplit[1]) : Protocol.DEFAULT_PORT;
return new HostAndPort(host, port); return new HostAndPort(host, port);
} }

View file

@ -4,6 +4,7 @@ import dev.xhyrom.lighteco.api.messenger.IncomingMessageConsumer;
import dev.xhyrom.lighteco.api.messenger.Messenger; import dev.xhyrom.lighteco.api.messenger.Messenger;
import dev.xhyrom.lighteco.api.messenger.MessengerProvider; import dev.xhyrom.lighteco.api.messenger.MessengerProvider;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
public class RedisMessengerProvider implements MessengerProvider { public class RedisMessengerProvider implements MessengerProvider {

View file

@ -1,9 +1,9 @@
package dev.xhyrom.lighteco.common.model.chat; package dev.xhyrom.lighteco.common.model.chat;
public abstract class AbstractCommandSender<T> implements CommandSender { public abstract class AbstractCommandSender<T> implements CommandSender {
protected final T delegate; protected final T delegate;
protected AbstractCommandSender(T delegate) { protected AbstractCommandSender(T delegate) {
this.delegate = delegate; this.delegate = delegate;
} }
} }

View file

@ -1,15 +1,18 @@
package dev.xhyrom.lighteco.common.model.chat; package dev.xhyrom.lighteco.common.model.chat;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.UUID; import java.util.UUID;
public interface CommandSender { public interface CommandSender {
String getUsername(); String getUsername();
@Nullable UUID getUniqueId(); @Nullable UUID getUniqueId();
boolean eligible(String permission); boolean eligible(String permission);
void sendMessage(Component message); void sendMessage(Component message);
default boolean isConsole() { default boolean isConsole() {

View file

@ -7,9 +7,12 @@ import dev.xhyrom.lighteco.common.cache.RedisBackedMap;
import dev.xhyrom.lighteco.common.messaging.InternalMessagingService; import dev.xhyrom.lighteco.common.messaging.InternalMessagingService;
import dev.xhyrom.lighteco.common.model.currency.Currency; import dev.xhyrom.lighteco.common.model.currency.Currency;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -31,6 +34,7 @@ public class User {
@Getter @Getter
@Setter @Setter
private boolean dirty = false; private boolean dirty = false;
@Getter @Getter
@Setter @Setter
private String username; private String username;
@ -51,54 +55,63 @@ public class User {
return balances.getOrDefault(currency, currency.getDefaultBalance()); return balances.getOrDefault(currency, currency.getDefaultBalance());
} }
public void setBalance(@NonNull Currency currency, @NonNull BigDecimal balance) throws CannotBeNegative, CannotBeGreaterThan { public void setBalance(@NonNull Currency currency, @NonNull BigDecimal balance)
throws CannotBeNegative, CannotBeGreaterThan {
this.setBalance(currency, balance, false, true); this.setBalance(currency, balance, false, true);
} }
public void setBalance(@NonNull Currency currency, @NonNull BigDecimal balance, boolean force) throws CannotBeNegative, CannotBeGreaterThan { public void setBalance(@NonNull Currency currency, @NonNull BigDecimal balance, boolean force)
throws CannotBeNegative, CannotBeGreaterThan {
this.setBalance(currency, balance, force, true); this.setBalance(currency, balance, force, true);
} }
public void setBalance(@NonNull Currency currency, @NonNull BigDecimal balance, boolean force, boolean publish) throws CannotBeNegative, CannotBeGreaterThan { public void setBalance(
@NonNull Currency currency, @NonNull BigDecimal balance, boolean force, boolean publish)
throws CannotBeNegative, CannotBeGreaterThan {
if (balance.compareTo(BigDecimal.ZERO) < 0) { if (balance.compareTo(BigDecimal.ZERO) < 0) {
throw new CannotBeNegative("Balance cannot be negative"); throw new CannotBeNegative("Balance cannot be negative");
} }
if (balance.compareTo(this.plugin.getConfig().maximumBalance) > 0) { if (balance.compareTo(this.plugin.getConfig().maximumBalance) > 0) {
throw new CannotBeGreaterThan("Balance cannot be greater than " + this.plugin.getConfig().maximumBalance); throw new CannotBeGreaterThan(
"Balance cannot be greater than " + this.plugin.getConfig().maximumBalance);
} }
balance = balance.setScale(currency.fractionalDigits(), RoundingMode.DOWN); balance = balance.setScale(currency.fractionalDigits(), RoundingMode.DOWN);
balances.put(currency, balance); balances.put(currency, balance);
if (!force) if (!force) this.setDirty(true);
this.setDirty(true);
if (publish) { if (publish) {
@NonNull Optional<InternalMessagingService> messagingService = this.plugin.getMessagingService(); @NonNull Optional<InternalMessagingService> messagingService = this.plugin.getMessagingService();
messagingService.ifPresent(internalMessagingService -> internalMessagingService.pushUserUpdate(this, currency)); messagingService.ifPresent(internalMessagingService ->
internalMessagingService.pushUserUpdate(this, currency));
} }
} }
public void deposit(@NonNull Currency currency, @NonNull BigDecimal amount) throws CannotBeNegative, CannotBeGreaterThan { public void deposit(@NonNull Currency currency, @NonNull BigDecimal amount)
throws CannotBeNegative, CannotBeGreaterThan {
if (amount.compareTo(BigDecimal.ZERO) < 0) { if (amount.compareTo(BigDecimal.ZERO) < 0) {
throw new IllegalArgumentException("Amount cannot be negative"); throw new IllegalArgumentException("Amount cannot be negative");
} }
if (amount.compareTo(this.plugin.getConfig().maximumBalance) > 0) { if (amount.compareTo(this.plugin.getConfig().maximumBalance) > 0) {
throw new CannotBeGreaterThan("Amount cannot be greater than " + this.plugin.getConfig().maximumBalance); throw new CannotBeGreaterThan(
"Amount cannot be greater than " + this.plugin.getConfig().maximumBalance);
} }
this.setBalance(currency, this.getBalance(currency).add(amount)); this.setBalance(currency, this.getBalance(currency).add(amount));
} }
public void withdraw(@NonNull Currency currency, @NonNull BigDecimal amount) throws CannotBeNegative, CannotBeGreaterThan { public void withdraw(@NonNull Currency currency, @NonNull BigDecimal amount)
throws CannotBeNegative, CannotBeGreaterThan {
if (amount.compareTo(BigDecimal.ZERO) < 0) { if (amount.compareTo(BigDecimal.ZERO) < 0) {
throw new IllegalArgumentException("Amount cannot be negative"); throw new IllegalArgumentException("Amount cannot be negative");
} }
if (amount.compareTo(this.plugin.getConfig().maximumBalance) > 0) { if (amount.compareTo(this.plugin.getConfig().maximumBalance) > 0) {
throw new CannotBeGreaterThan("Amount cannot be greater than " + this.plugin.getConfig().maximumBalance); throw new CannotBeGreaterThan(
"Amount cannot be greater than " + this.plugin.getConfig().maximumBalance);
} }
if (this.getBalance(currency).compareTo(amount) < 0) { if (this.getBalance(currency).compareTo(amount) < 0) {

View file

@ -6,14 +6,17 @@ import dev.xhyrom.lighteco.common.api.LightEcoApi;
import dev.xhyrom.lighteco.common.config.Config; import dev.xhyrom.lighteco.common.config.Config;
import dev.xhyrom.lighteco.common.dependencies.DependencyManager; import dev.xhyrom.lighteco.common.dependencies.DependencyManager;
import dev.xhyrom.lighteco.common.dependencies.DependencyManagerImpl; import dev.xhyrom.lighteco.common.dependencies.DependencyManagerImpl;
import dev.xhyrom.lighteco.common.messaging.MessagingFactory;
import dev.xhyrom.lighteco.common.messaging.InternalMessagingService; import dev.xhyrom.lighteco.common.messaging.InternalMessagingService;
import dev.xhyrom.lighteco.common.messaging.MessagingFactory;
import dev.xhyrom.lighteco.common.storage.Storage; import dev.xhyrom.lighteco.common.storage.Storage;
import dev.xhyrom.lighteco.common.storage.StorageFactory; import dev.xhyrom.lighteco.common.storage.StorageFactory;
import dev.xhyrom.lighteco.common.task.UserSaveTask; import dev.xhyrom.lighteco.common.task.UserSaveTask;
import eu.okaeri.configs.ConfigManager; import eu.okaeri.configs.ConfigManager;
import eu.okaeri.configs.yaml.snakeyaml.YamlSnakeYamlConfigurer; import eu.okaeri.configs.yaml.snakeyaml.YamlSnakeYamlConfigurer;
import lombok.Getter; import lombok.Getter;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.Optional; import java.util.Optional;
@ -22,11 +25,13 @@ import java.util.concurrent.TimeUnit;
@Getter @Getter
public abstract class AbstractLightEcoPlugin implements LightEcoPlugin { public abstract class AbstractLightEcoPlugin implements LightEcoPlugin {
private DependencyManager dependencyManager; private DependencyManager dependencyManager;
@Getter @Getter
private Config config; private Config config;
@Getter @Getter
private Storage storage; private Storage storage;
private InternalMessagingService messagingService; private InternalMessagingService messagingService;
private LightEcoApi api; private LightEcoApi api;
@ -47,14 +52,10 @@ public abstract class AbstractLightEcoPlugin implements LightEcoPlugin {
public final void enable() { public final void enable() {
// setup storage // setup storage
StorageFactory storageFactory = new StorageFactory(this); StorageFactory storageFactory = new StorageFactory(this);
this.dependencyManager.loadStorageDependencies( this.dependencyManager.loadStorageDependencies(storageFactory.getRequiredTypes());
storageFactory.getRequiredTypes()
);
MessagingFactory messagingFactory = this.getMessagingFactory(); MessagingFactory messagingFactory = this.getMessagingFactory();
this.dependencyManager.loadMessagingDependencies( this.dependencyManager.loadMessagingDependencies(messagingFactory.getRequiredTypes());
messagingFactory.getRequiredTypes()
);
this.storage = storageFactory.get(); this.storage = storageFactory.get();
this.messagingService = messagingFactory.get(); this.messagingService = messagingFactory.get();
@ -77,7 +78,9 @@ public abstract class AbstractLightEcoPlugin implements LightEcoPlugin {
this.registerApiOnPlatform(this.api); this.registerApiOnPlatform(this.api);
this.userSaveTask = new UserSaveTask(this); this.userSaveTask = new UserSaveTask(this);
this.getBootstrap().getScheduler().asyncRepeating(userSaveTask, this.config.saveInterval, TimeUnit.SECONDS); this.getBootstrap()
.getScheduler()
.asyncRepeating(userSaveTask, this.config.saveInterval, TimeUnit.SECONDS);
} }
public final void disable() { public final void disable() {
@ -90,8 +93,7 @@ public abstract class AbstractLightEcoPlugin implements LightEcoPlugin {
// shutdown storage // shutdown storage
this.storage.shutdown(); this.storage.shutdown();
if (this.messagingService != null) if (this.messagingService != null) this.messagingService.shutdown();
this.messagingService.shutdown();
// close isolated class loaders // close isolated class loaders
this.dependencyManager.close(); this.dependencyManager.close();
@ -100,10 +102,13 @@ public abstract class AbstractLightEcoPlugin implements LightEcoPlugin {
protected abstract void registerListeners(); protected abstract void registerListeners();
protected abstract void setupManagers(); protected abstract void setupManagers();
protected abstract MessagingFactory getMessagingFactory(); protected abstract MessagingFactory getMessagingFactory();
protected abstract void registerApiOnPlatform(LightEco api); protected abstract void registerApiOnPlatform(LightEco api);
protected abstract void registerPlatformHooks(); protected abstract void registerPlatformHooks();
protected abstract void removePlatformHooks(); protected abstract void removePlatformHooks();
@Override @Override

View file

@ -10,6 +10,7 @@ import dev.xhyrom.lighteco.common.manager.user.UserManager;
import dev.xhyrom.lighteco.common.messaging.InternalMessagingService; import dev.xhyrom.lighteco.common.messaging.InternalMessagingService;
import dev.xhyrom.lighteco.common.plugin.bootstrap.LightEcoBootstrap; import dev.xhyrom.lighteco.common.plugin.bootstrap.LightEcoBootstrap;
import dev.xhyrom.lighteco.common.storage.Storage; import dev.xhyrom.lighteco.common.storage.Storage;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.Optional; import java.util.Optional;
@ -20,9 +21,13 @@ public interface LightEcoPlugin {
@NonNull LightEcoBootstrap getBootstrap(); @NonNull LightEcoBootstrap getBootstrap();
@NonNull Config getConfig(); @NonNull Config getConfig();
@NonNull UserManager getUserManager(); @NonNull UserManager getUserManager();
@NonNull CurrencyManager getCurrencyManager(); @NonNull CurrencyManager getCurrencyManager();
@NonNull CommandManager getCommandManager(); @NonNull CommandManager getCommandManager();
@NonNull ContextManager<?> getContextManager(); @NonNull ContextManager<?> getContextManager();
@NonNull DependencyManager getDependencyManager(); @NonNull DependencyManager getDependencyManager();

View file

@ -2,6 +2,7 @@ package dev.xhyrom.lighteco.common.plugin.bootstrap;
import dev.xhyrom.lighteco.common.plugin.logger.PluginLogger; import dev.xhyrom.lighteco.common.plugin.logger.PluginLogger;
import dev.xhyrom.lighteco.common.plugin.scheduler.SchedulerAdapter; import dev.xhyrom.lighteco.common.plugin.scheduler.SchedulerAdapter;
import net.kyori.adventure.audience.Audience; import net.kyori.adventure.audience.Audience;
import java.io.InputStream; import java.io.InputStream;
@ -12,15 +13,22 @@ import java.util.UUID;
public interface LightEcoBootstrap { public interface LightEcoBootstrap {
Object getLoader(); Object getLoader();
PluginLogger getLogger(); PluginLogger getLogger();
SchedulerAdapter getScheduler(); SchedulerAdapter getScheduler();
Path getDataDirectory(); Path getDataDirectory();
String getVersion(); String getVersion();
Optional<UUID> lookupUniqueId(String username); Optional<UUID> lookupUniqueId(String username);
boolean isPlayerOnline(UUID uniqueId); boolean isPlayerOnline(UUID uniqueId);
List<UUID> getOnlinePlayers(); List<UUID> getOnlinePlayers();
InputStream getResourceStream(String filename); InputStream getResourceStream(String filename);
Audience getPlayerAudience(UUID uniqueId); Audience getPlayerAudience(UUID uniqueId);
} }

View file

@ -2,6 +2,8 @@ package dev.xhyrom.lighteco.common.plugin.bootstrap;
public interface LoaderBootstrap { public interface LoaderBootstrap {
void onLoad(); void onLoad();
void onEnable(); void onEnable();
void onDisable(); void onDisable();
} }

View file

@ -2,20 +2,26 @@ package dev.xhyrom.lighteco.common.plugin.logger;
public interface PluginLogger { public interface PluginLogger {
void info(String message); void info(String message);
void info(String message, Object ...args);
void info(String message, Object... args);
void debug(String message); void debug(String message);
void debug(String message, Object ...args);
void debug(String message, Object... args);
void warn(String message); void warn(String message);
void warn(String message, Object ...args);
void warn(String message, Object... args);
void warn(String message, Throwable throwable); void warn(String message, Throwable throwable);
void warn(String message, Throwable throwable, Object ...args);
void warn(String message, Throwable throwable, Object... args);
void error(String message); void error(String message);
void error(String message, Object ...args);
void error(String message, Object... args);
void error(String message, Throwable throwable); void error(String message, Throwable throwable);
void error(String message, Throwable throwable, Object ...args);
void error(String message, Throwable throwable, Object... args);
} }

View file

@ -75,7 +75,8 @@ public class Storage {
} }
return future(() -> this.provider.loadUser(uniqueId, username)) return future(() -> this.provider.loadUser(uniqueId, username))
.thenApply(apiUser -> this.plugin.getUserManager().getIfLoaded(apiUser.getUniqueId())); .thenApply(
apiUser -> this.plugin.getUserManager().getIfLoaded(apiUser.getUniqueId()));
} }
public CompletableFuture<Void> saveUser(dev.xhyrom.lighteco.api.model.user.User user) { public CompletableFuture<Void> saveUser(dev.xhyrom.lighteco.api.model.user.User user) {

View file

@ -37,25 +37,27 @@ public class StorageFactory {
case MEMORY -> new MemoryStorageProvider(this.plugin); case MEMORY -> new MemoryStorageProvider(this.plugin);
case H2 -> new SqlStorageProvider( case H2 -> new SqlStorageProvider(
this.plugin, this.plugin,
new H2ConnectionFactory(this.plugin.getBootstrap().getDataDirectory().resolve("lighteco-h2").toAbsolutePath()) new H2ConnectionFactory(this.plugin
); .getBootstrap()
.getDataDirectory()
.resolve("lighteco-h2")
.toAbsolutePath()));
case SQLITE -> new SqlStorageProvider( case SQLITE -> new SqlStorageProvider(
this.plugin, this.plugin,
new SqliteConnectionFactory(this.plugin.getBootstrap().getDataDirectory().resolve("lighteco-sqlite.db")) new SqliteConnectionFactory(this.plugin
); .getBootstrap()
.getDataDirectory()
.resolve("lighteco-sqlite.db")));
case MYSQL -> new SqlStorageProvider( case MYSQL -> new SqlStorageProvider(
this.plugin, this.plugin, new MySQLConnectionFactory(this.plugin.getConfig().storage.data));
new MySQLConnectionFactory(this.plugin.getConfig().storage.data)
);
case MARIADB -> new SqlStorageProvider( case MARIADB -> new SqlStorageProvider(
this.plugin, this.plugin,
new MariaDBConnectionFactory(this.plugin.getConfig().storage.data) new MariaDBConnectionFactory(this.plugin.getConfig().storage.data));
);
case POSTGRESQL -> new SqlStorageProvider( case POSTGRESQL -> new SqlStorageProvider(
this.plugin, this.plugin,
new PostgreSQLConnectionFactory(this.plugin.getConfig().storage.data) new PostgreSQLConnectionFactory(this.plugin.getConfig().storage.data));
); default -> throw new IllegalArgumentException(
default -> throw new IllegalArgumentException("Unknown storage provider: " + type.name()); "Unknown storage provider: " + type.name());
}; };
} }
} }

View file

@ -3,6 +3,7 @@ package dev.xhyrom.lighteco.common.storage.provider.memory;
import dev.xhyrom.lighteco.api.model.user.User; import dev.xhyrom.lighteco.api.model.user.User;
import dev.xhyrom.lighteco.api.storage.StorageProvider; import dev.xhyrom.lighteco.api.storage.StorageProvider;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
@ -13,6 +14,7 @@ public class MemoryStorageProvider implements StorageProvider {
private HashMap<UUID, User> userDatabase; private HashMap<UUID, User> userDatabase;
private final LightEcoPlugin plugin; private final LightEcoPlugin plugin;
public MemoryStorageProvider(LightEcoPlugin plugin) { public MemoryStorageProvider(LightEcoPlugin plugin) {
this.plugin = plugin; this.plugin = plugin;
} }
@ -49,9 +51,9 @@ public class MemoryStorageProvider implements StorageProvider {
} }
private User createUser(UUID uniqueId, String username, User data) { private User createUser(UUID uniqueId, String username, User data) {
dev.xhyrom.lighteco.common.model.user.User user = this.plugin.getUserManager().getOrMake(uniqueId); dev.xhyrom.lighteco.common.model.user.User user =
if (username != null) this.plugin.getUserManager().getOrMake(uniqueId);
user.setUsername(username); if (username != null) user.setUsername(username);
return user.getProxy(); return user.getProxy();
} }

View file

@ -7,26 +7,22 @@ public enum SqlStatements {
"INSERT INTO '{prefix}_local_{context}_{currency}_users' (uuid, balance) VALUES (?1, ?2) ON CONFLICT (uuid) DO UPDATE SET balance=?2;", "INSERT INTO '{prefix}_local_{context}_{currency}_users' (uuid, balance) VALUES (?1, ?2) ON CONFLICT (uuid) DO UPDATE SET balance=?2;",
"INSERT INTO '{prefix}_local_{context}_{currency}_users' (uuid, balance) VALUES (?1, ?2) ON DUPLICATE KEY UPDATE balance=?2;", "INSERT INTO '{prefix}_local_{context}_{currency}_users' (uuid, balance) VALUES (?1, ?2) ON DUPLICATE KEY UPDATE balance=?2;",
"INSERT INTO '{prefix}_local_{context}_{currency}_users' (uuid, balance) VALUES (?, ?) ON DUPLICATE KEY UPDATE balance=?;", "INSERT INTO '{prefix}_local_{context}_{currency}_users' (uuid, balance) VALUES (?, ?) ON DUPLICATE KEY UPDATE balance=?;",
"INSERT INTO '{prefix}_local_{context}_{currency}_users' (uuid, balance) VALUES (?1, ?2) ON CONFLICT (uuid) DO UPDATE SET balance=?2;" "INSERT INTO '{prefix}_local_{context}_{currency}_users' (uuid, balance) VALUES (?1, ?2) ON CONFLICT (uuid) DO UPDATE SET balance=?2;"),
),
SAVE_USER_GLOBAL_CURRENCY( SAVE_USER_GLOBAL_CURRENCY(
"INSERT INTO '{prefix}_global_{currency}_users' (uuid, balance) VALUES (?1, ?2) ON CONFLICT (uuid) DO UPDATE SET balance=?2;", "INSERT INTO '{prefix}_global_{currency}_users' (uuid, balance) VALUES (?1, ?2) ON CONFLICT (uuid) DO UPDATE SET balance=?2;",
"INSERT INTO '{prefix}_global_{currency}_users' (uuid, balance) VALUES (?1, ?2) ON DUPLICATE KEY UPDATE balance=?2;", "INSERT INTO '{prefix}_global_{currency}_users' (uuid, balance) VALUES (?1, ?2) ON DUPLICATE KEY UPDATE balance=?2;",
"INSERT INTO '{prefix}_global_{currency}_users' (uuid, balance) VALUES (?, ?) ON DUPLICATE KEY UPDATE balance=?;", "INSERT INTO '{prefix}_global_{currency}_users' (uuid, balance) VALUES (?, ?) ON DUPLICATE KEY UPDATE balance=?;",
"INSERT INTO '{prefix}_global_{currency}_users' (uuid, balance) VALUES (?1, ?2) ON CONFLICT (uuid) DO UPDATE SET balance=?2;" "INSERT INTO '{prefix}_global_{currency}_users' (uuid, balance) VALUES (?1, ?2) ON CONFLICT (uuid) DO UPDATE SET balance=?2;"),
),
LOAD_LOCAL_CURRENCY_USER( LOAD_LOCAL_CURRENCY_USER(
"SELECT {identifier} AS name, balance FROM '{prefix}_local_{context}_{currency}_users' WHERE uuid = ?1", "SELECT {identifier} AS name, balance FROM '{prefix}_local_{context}_{currency}_users' WHERE uuid = ?1",
"SELECT {identifier} AS name, balance FROM '{prefix}_local_{context}_{currency}_users' WHERE uuid = ?1", "SELECT {identifier} AS name, balance FROM '{prefix}_local_{context}_{currency}_users' WHERE uuid = ?1",
"SELECT {identifier} AS name, balance FROM '{prefix}_local_{context}_{currency}_users' WHERE uuid = ?", "SELECT {identifier} AS name, balance FROM '{prefix}_local_{context}_{currency}_users' WHERE uuid = ?",
"SELECT {identifier} AS name, balance FROM '{prefix}_local_{context}_{currency}_users' WHERE uuid = ?1" "SELECT {identifier} AS name, balance FROM '{prefix}_local_{context}_{currency}_users' WHERE uuid = ?1"),
),
LOAD_GLOBAL_CURRENCY_USER( LOAD_GLOBAL_CURRENCY_USER(
"SELECT {identifier} AS name, balance FROM '{prefix}_global_{currency}_users' WHERE uuid = ?1", "SELECT {identifier} AS name, balance FROM '{prefix}_global_{currency}_users' WHERE uuid = ?1",
"SELECT {identifier} AS name, balance FROM '{prefix}_global_{currency}_users' WHERE uuid = ?1", "SELECT {identifier} AS name, balance FROM '{prefix}_global_{currency}_users' WHERE uuid = ?1",
"SELECT {identifier} AS name, balance FROM '{prefix}_global_{currency}_users' WHERE uuid = ?", "SELECT {identifier} AS name, balance FROM '{prefix}_global_{currency}_users' WHERE uuid = ?",
"SELECT {identifier} AS name, balance FROM '{prefix}_global_{currency}_users' WHERE uuid = ?1" "SELECT {identifier} AS name, balance FROM '{prefix}_global_{currency}_users' WHERE uuid = ?1");
);
public final String sqlite; public final String sqlite;
public final String mysql; public final String mysql;
@ -54,11 +50,13 @@ public enum SqlStatements {
case POSTGRESQL -> { case POSTGRESQL -> {
return this.postgresql; return this.postgresql;
} }
default -> throw new IllegalArgumentException("Unknown implementation: " + implementationName); default -> throw new IllegalArgumentException(
"Unknown implementation: " + implementationName);
} }
} }
public static boolean mustDuplicateParameters(StorageType implementationName) { public static boolean mustDuplicateParameters(StorageType implementationName) {
return implementationName == StorageType.MARIADB || implementationName == StorageType.POSTGRESQL; return implementationName == StorageType.MARIADB
|| implementationName == StorageType.POSTGRESQL;
} }
} }

View file

@ -6,6 +6,7 @@ import dev.xhyrom.lighteco.common.model.currency.Currency;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import dev.xhyrom.lighteco.common.storage.StorageType; import dev.xhyrom.lighteco.common.storage.StorageType;
import dev.xhyrom.lighteco.common.storage.provider.sql.connection.ConnectionFactory; import dev.xhyrom.lighteco.common.storage.provider.sql.connection.ConnectionFactory;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
@ -25,15 +26,19 @@ public class SqlStorageProvider implements StorageProvider {
private static String LOAD_LOCAL_CURRENCY_USER; private static String LOAD_LOCAL_CURRENCY_USER;
private static String LOAD_GLOBAL_CRRENCY_USER; private static String LOAD_GLOBAL_CRRENCY_USER;
private static final String DELETE_LOCAL_USER = "DELETE FROM {prefix}_local_{context}_{currency}_users WHERE uuid = ?;"; private static final String DELETE_LOCAL_USER =
private static final String DELETE_GLOBAL_USER = "DELETE FROM {prefix}_global_{currency}_users WHERE uuid = ?;"; "DELETE FROM {prefix}_local_{context}_{currency}_users WHERE uuid = ?;";
private static final String CREATE_TABLE = """ private static final String DELETE_GLOBAL_USER =
"DELETE FROM {prefix}_global_{currency}_users WHERE uuid = ?;";
private static final String CREATE_TABLE =
"""
CREATE TABLE IF NOT EXISTS '{prefix}_{table}' ( CREATE TABLE IF NOT EXISTS '{prefix}_{table}' (
'uuid' VARCHAR(36) NOT NULL, 'uuid' VARCHAR(36) NOT NULL,
'balance' DECIMAL(20, 2) NOT NULL, 'balance' DECIMAL(20, 2) NOT NULL,
PRIMARY KEY (`uuid`) PRIMARY KEY (`uuid`)
); );
""".trim(); """
.trim();
private final LightEcoPlugin plugin; private final LightEcoPlugin plugin;
private final ConnectionFactory connectionFactory; private final ConnectionFactory connectionFactory;
@ -42,11 +47,9 @@ public class SqlStorageProvider implements StorageProvider {
public SqlStorageProvider(LightEcoPlugin plugin, ConnectionFactory connectionFactory) { public SqlStorageProvider(LightEcoPlugin plugin, ConnectionFactory connectionFactory) {
this.plugin = plugin; this.plugin = plugin;
this.connectionFactory = connectionFactory; this.connectionFactory = connectionFactory;
this.statementProcessor = connectionFactory.getStatementProcessor().compose( this.statementProcessor = connectionFactory.getStatementProcessor().compose(s -> s.replace(
s -> s "{prefix}", plugin.getConfig().storage.tablePrefix)
.replace("{prefix}", plugin.getConfig().storage.tablePrefix) .replace("{context}", plugin.getConfig().server));
.replace("{context}", plugin.getConfig().server)
);
final StorageType implementationName = this.connectionFactory.getImplementationName(); final StorageType implementationName = this.connectionFactory.getImplementationName();
SAVE_USER_LOCAL_CURRENCY = SqlStatements.SAVE_USER_LOCAL_CURRENCY.get(implementationName); SAVE_USER_LOCAL_CURRENCY = SqlStatements.SAVE_USER_LOCAL_CURRENCY.get(implementationName);
@ -66,7 +69,8 @@ public class SqlStorageProvider implements StorageProvider {
} }
@Override @Override
public void registerCurrency(dev.xhyrom.lighteco.api.model.currency.@NonNull Currency currency) throws Exception { public void registerCurrency(dev.xhyrom.lighteco.api.model.currency.@NonNull Currency currency)
throws Exception {
StringBuilder tableName = new StringBuilder(); StringBuilder tableName = new StringBuilder();
if (currency.getType() == dev.xhyrom.lighteco.api.model.currency.Currency.Type.LOCAL) { if (currency.getType() == dev.xhyrom.lighteco.api.model.currency.Currency.Type.LOCAL) {
@ -80,41 +84,39 @@ public class SqlStorageProvider implements StorageProvider {
tableName.append("_users"); tableName.append("_users");
try (Connection c = this.connectionFactory.getConnection()) { try (Connection c = this.connectionFactory.getConnection()) {
try (PreparedStatement ps = c.prepareStatement( try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(
this.statementProcessor.apply(CREATE_TABLE CREATE_TABLE.replace("{table}", tableName.toString())))) {
.replace("{table}", tableName.toString())
)
)) {
ps.execute(); ps.execute();
} }
} }
} }
@Override @Override
public @NonNull User loadUser(@NonNull UUID uniqueId, @Nullable String username) throws Exception { public @NonNull User loadUser(@NonNull UUID uniqueId, @Nullable String username)
throws Exception {
String uniqueIdString = uniqueId.toString(); String uniqueIdString = uniqueId.toString();
dev.xhyrom.lighteco.common.model.user.User user = this.plugin.getUserManager().getOrMake(uniqueId); dev.xhyrom.lighteco.common.model.user.User user =
if (username != null) this.plugin.getUserManager().getOrMake(uniqueId);
user.setUsername(username); if (username != null) user.setUsername(username);
StringBuilder query = new StringBuilder(); StringBuilder query = new StringBuilder();
List<Currency> currencies = this.plugin.getCurrencyManager().getRegisteredCurrencies().stream().toList(); List<Currency> currencies =
this.plugin.getCurrencyManager().getRegisteredCurrencies().stream()
.toList();
int size = this.plugin.getCurrencyManager().getRegisteredCurrencies().size(); int size = this.plugin.getCurrencyManager().getRegisteredCurrencies().size();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
Currency currency = currencies.get(i); Currency currency = currencies.get(i);
switch (currency.getType()) { switch (currency.getType()) {
case GLOBAL -> query.append( case GLOBAL -> query.append(this.statementProcessor
this.statementProcessor.apply(LOAD_GLOBAL_CRRENCY_USER .apply(LOAD_GLOBAL_CRRENCY_USER.replace(
.replace("{currency}", currency.getIdentifier()) "{currency}", currency.getIdentifier()))
).replace("{identifier}", "'"+currency.getIdentifier()+"'") .replace("{identifier}", "'" + currency.getIdentifier() + "'"));
); case LOCAL -> query.append(this.statementProcessor
case LOCAL -> query.append( .apply(LOAD_LOCAL_CURRENCY_USER.replace(
this.statementProcessor.apply(LOAD_LOCAL_CURRENCY_USER "{currency}", currency.getIdentifier()))
.replace("{currency}", currency.getIdentifier()) .replace("{identifier}", "'" + currency.getIdentifier() + "'"));
).replace("{identifier}", "'"+currency.getIdentifier()+"'")
);
} }
if (i != size - 1) { if (i != size - 1) {
@ -124,7 +126,8 @@ public class SqlStorageProvider implements StorageProvider {
try (Connection c = this.connectionFactory.getConnection()) { try (Connection c = this.connectionFactory.getConnection()) {
try (PreparedStatement ps = c.prepareStatement(query.toString())) { try (PreparedStatement ps = c.prepareStatement(query.toString())) {
if (SqlStatements.mustDuplicateParameters(this.connectionFactory.getImplementationName())) { if (SqlStatements.mustDuplicateParameters(
this.connectionFactory.getImplementationName())) {
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
ps.setString(i + 1, uniqueIdString); ps.setString(i + 1, uniqueIdString);
} }
@ -186,9 +189,9 @@ public class SqlStorageProvider implements StorageProvider {
saveBalances(c, user, uniqueIdString, true); saveBalances(c, user, uniqueIdString, true);
} }
private void saveBalances(Connection c, User user, String uniqueIdString, boolean transactions) throws SQLException { private void saveBalances(Connection c, User user, String uniqueIdString, boolean transactions)
if (transactions) throws SQLException {
c.setAutoCommit(false); if (transactions) c.setAutoCommit(false);
for (Currency currency : this.plugin.getCurrencyManager().getRegisteredCurrencies()) { for (Currency currency : this.plugin.getCurrencyManager().getRegisteredCurrencies()) {
BigDecimal balance = user.getBalance(currency.getProxy()); BigDecimal balance = user.getBalance(currency.getProxy());
@ -196,16 +199,18 @@ public class SqlStorageProvider implements StorageProvider {
if (balance.compareTo(BigDecimal.ZERO) == 0) { if (balance.compareTo(BigDecimal.ZERO) == 0) {
switch (currency.getType()) { switch (currency.getType()) {
case GLOBAL -> { case GLOBAL -> {
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(DELETE_GLOBAL_USER try (PreparedStatement ps = c.prepareStatement(
.replace("{currency}", currency.getIdentifier())))) { this.statementProcessor.apply(DELETE_GLOBAL_USER.replace(
"{currency}", currency.getIdentifier())))) {
ps.setString(1, uniqueIdString); ps.setString(1, uniqueIdString);
ps.execute(); ps.execute();
} }
} }
case LOCAL -> { case LOCAL -> {
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(DELETE_LOCAL_USER try (PreparedStatement ps = c.prepareStatement(
.replace("{currency}", currency.getIdentifier())))) { this.statementProcessor.apply(DELETE_LOCAL_USER.replace(
"{currency}", currency.getIdentifier())))) {
ps.setString(1, uniqueIdString); ps.setString(1, uniqueIdString);
ps.execute(); ps.execute();
@ -218,22 +223,26 @@ public class SqlStorageProvider implements StorageProvider {
switch (currency.getType()) { switch (currency.getType()) {
case GLOBAL -> { case GLOBAL -> {
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(SAVE_USER_GLOBAL_CURRENCY try (PreparedStatement ps = c.prepareStatement(
.replace("{currency}", currency.getIdentifier())))) { this.statementProcessor.apply(SAVE_USER_GLOBAL_CURRENCY.replace(
"{currency}", currency.getIdentifier())))) {
ps.setString(1, uniqueIdString); ps.setString(1, uniqueIdString);
ps.setBigDecimal(2, balance); ps.setBigDecimal(2, balance);
if (SqlStatements.mustDuplicateParameters(this.connectionFactory.getImplementationName())) if (SqlStatements.mustDuplicateParameters(
this.connectionFactory.getImplementationName()))
ps.setBigDecimal(3, balance); ps.setBigDecimal(3, balance);
ps.execute(); ps.execute();
} }
} }
case LOCAL -> { case LOCAL -> {
try (PreparedStatement psLocal = c.prepareStatement(this.statementProcessor.apply(SAVE_USER_LOCAL_CURRENCY try (PreparedStatement psLocal = c.prepareStatement(
.replace("{currency}", currency.getIdentifier())))) { this.statementProcessor.apply(SAVE_USER_LOCAL_CURRENCY.replace(
"{currency}", currency.getIdentifier())))) {
psLocal.setString(1, uniqueIdString); psLocal.setString(1, uniqueIdString);
psLocal.setBigDecimal(2, balance); psLocal.setBigDecimal(2, balance);
if (SqlStatements.mustDuplicateParameters(this.connectionFactory.getImplementationName())) if (SqlStatements.mustDuplicateParameters(
this.connectionFactory.getImplementationName()))
psLocal.setBigDecimal(3, balance); psLocal.setBigDecimal(3, balance);
psLocal.execute(); psLocal.execute();

View file

@ -10,6 +10,7 @@ public interface ConnectionFactory {
StorageType getImplementationName(); StorageType getImplementationName();
void init(LightEcoPlugin plugin); void init(LightEcoPlugin plugin);
void shutdown() throws Exception; void shutdown() throws Exception;
Function<String, String> getStatementProcessor(); Function<String, String> getStatementProcessor();

View file

@ -26,11 +26,13 @@ public class H2ConnectionFactory extends FileConnectionFactory {
@Override @Override
public void init(LightEcoPlugin plugin) { public void init(LightEcoPlugin plugin) {
ClassLoader classLoader = plugin.getDependencyManager().obtainClassLoaderWith(EnumSet.of(Dependency.H2_DRIVER)); ClassLoader classLoader = plugin.getDependencyManager()
.obtainClassLoaderWith(EnumSet.of(Dependency.H2_DRIVER));
try { try {
Class<?> connectionClass = classLoader.loadClass("org.h2.jdbc.JdbcConnection"); Class<?> connectionClass = classLoader.loadClass("org.h2.jdbc.JdbcConnection");
this.connectionConstructor = connectionClass.getConstructor(String.class, Properties.class, String.class, Object.class, boolean.class); this.connectionConstructor = connectionClass.getConstructor(
String.class, Properties.class, String.class, Object.class, boolean.class);
} catch (ReflectiveOperationException e) { } catch (ReflectiveOperationException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -42,8 +44,9 @@ public class H2ConnectionFactory extends FileConnectionFactory {
return (Connection) this.connectionConstructor.newInstance( return (Connection) this.connectionConstructor.newInstance(
"jdbc:h2:" + file.toString() + ";MODE=MySQL;DATABASE_TO_LOWER=TRUE", "jdbc:h2:" + file.toString() + ";MODE=MySQL;DATABASE_TO_LOWER=TRUE",
new Properties(), new Properties(),
null, null, false null,
); null,
false);
} catch (Exception e) { } catch (Exception e) {
if (e.getCause() instanceof SQLException) { if (e.getCause() instanceof SQLException) {
throw (SQLException) e.getCause(); throw (SQLException) e.getCause();
@ -55,8 +58,7 @@ public class H2ConnectionFactory extends FileConnectionFactory {
@Override @Override
public Function<String, String> getStatementProcessor() { public Function<String, String> getStatementProcessor() {
return s -> s return s -> s.replace('\'', '`')
.replace('\'', '`')
.replace("LIKE", "ILIKE") .replace("LIKE", "ILIKE")
.replace("value", "`value`") .replace("value", "`value`")
.replace("``value``", "`value`"); .replace("``value``", "`value`");

View file

@ -26,11 +26,13 @@ public class SqliteConnectionFactory extends FileConnectionFactory {
@Override @Override
public void init(LightEcoPlugin plugin) { public void init(LightEcoPlugin plugin) {
ClassLoader classLoader = plugin.getDependencyManager().obtainClassLoaderWith(EnumSet.of(Dependency.SQLITE_DRIVER)); ClassLoader classLoader = plugin.getDependencyManager()
.obtainClassLoaderWith(EnumSet.of(Dependency.SQLITE_DRIVER));
try { try {
Class<?> connectionClass = classLoader.loadClass("org.sqlite.jdbc4.JDBC4Connection"); Class<?> connectionClass = classLoader.loadClass("org.sqlite.jdbc4.JDBC4Connection");
this.connectionConstructor = connectionClass.getConstructor(String.class, String.class, Properties.class); this.connectionConstructor =
connectionClass.getConstructor(String.class, String.class, Properties.class);
} catch (ReflectiveOperationException e) { } catch (ReflectiveOperationException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -40,10 +42,7 @@ public class SqliteConnectionFactory extends FileConnectionFactory {
protected Connection createConnection(Path file) throws SQLException { protected Connection createConnection(Path file) throws SQLException {
try { try {
return (Connection) this.connectionConstructor.newInstance( return (Connection) this.connectionConstructor.newInstance(
"jdbc:sqlite:" + file, "jdbc:sqlite:" + file, file.toString(), new Properties());
file.toString(),
new Properties()
);
} catch (Exception e) { } catch (Exception e) {
if (e.getCause() instanceof SQLException) { if (e.getCause() instanceof SQLException) {
throw (SQLException) e.getCause(); throw (SQLException) e.getCause();

View file

@ -1,6 +1,7 @@
package dev.xhyrom.lighteco.common.storage.provider.sql.connection.hikari; package dev.xhyrom.lighteco.common.storage.provider.sql.connection.hikari;
import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariConfig;
import dev.xhyrom.lighteco.common.config.storage.StorageDataConfig; import dev.xhyrom.lighteco.common.config.storage.StorageDataConfig;
import java.sql.Driver; import java.sql.Driver;
@ -18,9 +19,16 @@ public abstract class DriverBasedHikariConnectionFactory extends HikariConnectio
protected abstract String driverJdbcIdentifier(); protected abstract String driverJdbcIdentifier();
@Override @Override
protected void configureDatabase(HikariConfig config, String address, String port, String databaseName, String username, String password) { protected void configureDatabase(
HikariConfig config,
String address,
String port,
String databaseName,
String username,
String password) {
config.setDriverClassName(driverClassName()); config.setDriverClassName(driverClassName());
config.setJdbcUrl(String.format("jdbc:%s://%s:%s/%s", driverJdbcIdentifier(), address, port, databaseName)); config.setJdbcUrl(String.format(
"jdbc:%s://%s:%s/%s", driverJdbcIdentifier(), address, port, databaseName));
config.setUsername(username); config.setUsername(username);
config.setPassword(password); config.setPassword(password);
} }
@ -39,7 +47,8 @@ public abstract class DriverBasedHikariConnectionFactory extends HikariConnectio
if (driver.getClass().getName().equals(driverClassName)) { if (driver.getClass().getName().equals(driverClassName)) {
try { try {
DriverManager.deregisterDriver(driver); DriverManager.deregisterDriver(driver);
} catch (SQLException ignored) {} } catch (SQLException ignored) {
}
} }
} }
} }

View file

@ -2,6 +2,7 @@ package dev.xhyrom.lighteco.common.storage.provider.sql.connection.hikari;
import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource; import com.zaxxer.hikari.HikariDataSource;
import dev.xhyrom.lighteco.common.config.storage.StorageDataConfig; import dev.xhyrom.lighteco.common.config.storage.StorageDataConfig;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import dev.xhyrom.lighteco.common.storage.provider.sql.connection.ConnectionFactory; import dev.xhyrom.lighteco.common.storage.provider.sql.connection.ConnectionFactory;
@ -23,7 +24,13 @@ public abstract class HikariConnectionFactory implements ConnectionFactory {
protected abstract String defaultPort(); protected abstract String defaultPort();
protected abstract void configureDatabase(HikariConfig config, String address, String port, String databaseName, String username, String password); protected abstract void configureDatabase(
HikariConfig config,
String address,
String port,
String databaseName,
String username,
String password);
protected void overrideProperties(Map<String, Object> properties) { protected void overrideProperties(Map<String, Object> properties) {
// https://github.com/brettwooldridge/HikariCP/wiki/Rapid-Recovery // https://github.com/brettwooldridge/HikariCP/wiki/Rapid-Recovery
@ -39,9 +46,7 @@ public abstract class HikariConnectionFactory implements ConnectionFactory {
/** /**
* Called after the Hikari pool has been initialised * Called after the Hikari pool has been initialised
*/ */
protected void postInitialize() { protected void postInitialize() {}
}
@Override @Override
public void init(LightEcoPlugin plugin) { public void init(LightEcoPlugin plugin) {
@ -56,7 +61,13 @@ public abstract class HikariConnectionFactory implements ConnectionFactory {
String port = addressSplit.length > 1 ? addressSplit[1] : defaultPort(); String port = addressSplit.length > 1 ? addressSplit[1] : defaultPort();
// allow the implementation to configure the HikariConfig appropriately with these values // allow the implementation to configure the HikariConfig appropriately with these values
configureDatabase(config, address, port, this.configuration.database, this.configuration.username, this.configuration.password); configureDatabase(
config,
address,
port,
this.configuration.database,
this.configuration.username,
this.configuration.password);
Map<String, Object> properties = new HashMap<>(); Map<String, Object> properties = new HashMap<>();
@ -91,7 +102,8 @@ public abstract class HikariConnectionFactory implements ConnectionFactory {
Connection connection = this.hikari.getConnection(); Connection connection = this.hikari.getConnection();
if (connection == null) { if (connection == null) {
throw new SQLException("Unable to get a connection from the pool. (getConnection returned null)"); throw new SQLException(
"Unable to get a connection from the pool. (getConnection returned null)");
} }
return connection; return connection;

View file

@ -30,11 +30,11 @@ public class UserSaveTask implements Runnable {
user.setDirty(false); user.setDirty(false);
} }
this.plugin.getStorage().saveUsersSync( this.plugin
Arrays.stream(users) .getStorage()
.saveUsersSync(Arrays.stream(users)
.map(User::getProxy) .map(User::getProxy)
.toArray(dev.xhyrom.lighteco.api.model.user.User[]::new) .toArray(dev.xhyrom.lighteco.api.model.user.User[]::new));
);
} catch (RuntimeException e) { } catch (RuntimeException e) {
this.plugin.getBootstrap().getLogger().error("Failed to save users", e); this.plugin.getBootstrap().getLogger().error("Failed to save users", e);
} }

View file

@ -4,4 +4,3 @@ package dev.xhyrom.lighteco.common.util;
public interface ThrowableRunnable { public interface ThrowableRunnable {
void run() throws Exception; void run() throws Exception;
} }

View file

@ -7,6 +7,7 @@
package dev.xhyrom.lighteco.common.util; package dev.xhyrom.lighteco.common.util;
import dev.xhyrom.lighteco.common.util.exception.UnableToInjectException; import dev.xhyrom.lighteco.common.util.exception.UnableToInjectException;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@ -22,9 +23,10 @@ public abstract class URLClassLoaderAccess {
} else if (Unsafe.isSupported()) { } else if (Unsafe.isSupported()) {
return new Unsafe(classLoader); return new Unsafe(classLoader);
} else { } else {
throw new UnableToInjectException("LightEco is unable to inject dependencies into the plugin class loader.\n" + throw new UnableToInjectException(
"To fix this, please add '--add-opens java.base/java.lang=ALL-UNNAMED' to your JVM arguments." + "LightEco is unable to inject dependencies into the plugin class loader.\n"
"If it still doesn't work, please report this on https://github.com/xHyroM/lighteco/issues"); + "To fix this, please add '--add-opens java.base/java.lang=ALL-UNNAMED' to your JVM arguments."
+ "If it still doesn't work, please report this on https://github.com/xHyroM/lighteco/issues");
} }
} }
@ -109,7 +111,9 @@ public abstract class URLClassLoaderAccess {
this.pathURLs = pathURLs; this.pathURLs = pathURLs;
} }
private static Object fetchField(final Class<?> clazz, final Object object, final String name) throws NoSuchFieldException { private static Object fetchField(
final Class<?> clazz, final Object object, final String name)
throws NoSuchFieldException {
Field field = clazz.getDeclaredField(name); Field field = clazz.getDeclaredField(name);
long offset = UNSAFE.objectFieldOffset(field); long offset = UNSAFE.objectFieldOffset(field);
return UNSAFE.getObject(object, offset); return UNSAFE.getObject(object, offset);
@ -121,7 +125,7 @@ public abstract class URLClassLoaderAccess {
throw new NullPointerException("unopenedURLs or pathURLs"); throw new NullPointerException("unopenedURLs or pathURLs");
} }
synchronized (this.unopenedURLs) { synchronized (this.unopenedURLs) {
this.unopenedURLs.add(url); this.unopenedURLs.add(url);
this.pathURLs.add(url); this.pathURLs.add(url);
} }

View file

@ -1,8 +1,10 @@
package dev.xhyrom.lighteco.currency.money.common; package dev.xhyrom.lighteco.currency.money.common;
import dev.xhyrom.lighteco.currency.money.common.config.Config; import dev.xhyrom.lighteco.currency.money.common.config.Config;
import eu.okaeri.configs.ConfigManager; import eu.okaeri.configs.ConfigManager;
import eu.okaeri.configs.yaml.snakeyaml.YamlSnakeYamlConfigurer; import eu.okaeri.configs.yaml.snakeyaml.YamlSnakeYamlConfigurer;
import lombok.Getter; import lombok.Getter;
import java.nio.file.Path; import java.nio.file.Path;

View file

@ -5,9 +5,9 @@ import eu.okaeri.configs.annotation.Comment;
public class Config extends OkaeriConfig { public class Config extends OkaeriConfig {
@Comment("Currency name") @Comment("Currency name")
@Comment("In singular form") @Comment("In singular form")
public String currencyNameSingular = "Dollar"; public String currencyNameSingular = "Dollar";
@Comment("In plural form") @Comment("In plural form")
public String currencyNamePlural = "Dollars"; public String currencyNamePlural = "Dollars";

View file

@ -19,7 +19,7 @@ public class MoneyCurrency implements Currency {
@Override @Override
public String[] getIdentifierAliases() { public String[] getIdentifierAliases() {
return new String[]{"eco"}; return new String[] {"eco"};
} }
@Override @Override
@ -39,6 +39,6 @@ public class MoneyCurrency implements Currency {
@Override @Override
public int fractionalDigits() { public int fractionalDigits() {
return this.plugin.getConfig().fractionalDigits; return this.plugin.getConfig().fractionalDigits;
} }
} }

View file

@ -5,15 +5,18 @@ import dev.xhyrom.lighteco.api.LightEcoProvider;
import dev.xhyrom.lighteco.api.manager.CommandManager; import dev.xhyrom.lighteco.api.manager.CommandManager;
import dev.xhyrom.lighteco.api.manager.CurrencyManager; import dev.xhyrom.lighteco.api.manager.CurrencyManager;
import dev.xhyrom.lighteco.api.model.currency.Currency; import dev.xhyrom.lighteco.api.model.currency.Currency;
import dev.xhyrom.lighteco.currency.money.paper.hooks.vault.VaultFactory;
import dev.xhyrom.lighteco.currency.money.common.AbstractPlugin; import dev.xhyrom.lighteco.currency.money.common.AbstractPlugin;
import dev.xhyrom.lighteco.currency.money.common.Plugin; import dev.xhyrom.lighteco.currency.money.common.Plugin;
import dev.xhyrom.lighteco.currency.money.common.currency.MoneyCurrency; import dev.xhyrom.lighteco.currency.money.common.currency.MoneyCurrency;
import dev.xhyrom.lighteco.currency.money.paper.hooks.vault.VaultFactory;
import lombok.Getter; import lombok.Getter;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
public class PaperMCLoader extends JavaPlugin { public class PaperMCLoader extends JavaPlugin {
private VaultFactory vaultFactory; private VaultFactory vaultFactory;
@Getter @Getter
private final Plugin plugin; private final Plugin plugin;
@ -50,4 +53,3 @@ public class PaperMCLoader extends JavaPlugin {
this.vaultFactory.unhook(); this.vaultFactory.unhook();
} }
} }

View file

@ -7,8 +7,10 @@ import dev.xhyrom.lighteco.api.exception.CannotBeNegative;
import dev.xhyrom.lighteco.api.model.currency.Currency; import dev.xhyrom.lighteco.api.model.currency.Currency;
import dev.xhyrom.lighteco.api.model.user.User; import dev.xhyrom.lighteco.api.model.user.User;
import dev.xhyrom.lighteco.currency.money.common.Plugin; import dev.xhyrom.lighteco.currency.money.common.Plugin;
import net.milkbowl.vault.economy.AbstractEconomy; import net.milkbowl.vault.economy.AbstractEconomy;
import net.milkbowl.vault.economy.EconomyResponse; import net.milkbowl.vault.economy.EconomyResponse;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -93,7 +95,7 @@ public class Vault extends AbstractEconomy {
@Override @Override
public boolean has(String playerName, double amount) { public boolean has(String playerName, double amount) {
return has(playerName, null, amount); return has(playerName, null, amount);
} }
@Override @Override
@ -121,16 +123,14 @@ public class Vault extends AbstractEconomy {
amount, amount,
bigDecimalToDouble(user.getBalance(currency)), bigDecimalToDouble(user.getBalance(currency)),
EconomyResponse.ResponseType.FAILURE, EconomyResponse.ResponseType.FAILURE,
e.getMessage() e.getMessage());
);
} }
return new EconomyResponse( return new EconomyResponse(
amount, amount,
bigDecimalToDouble(user.getBalance(currency)), bigDecimalToDouble(user.getBalance(currency)),
EconomyResponse.ResponseType.SUCCESS, EconomyResponse.ResponseType.SUCCESS,
"" "");
);
} }
@Override @Override
@ -150,16 +150,14 @@ public class Vault extends AbstractEconomy {
amount, amount,
bigDecimalToDouble(user.getBalance(currency)), bigDecimalToDouble(user.getBalance(currency)),
EconomyResponse.ResponseType.FAILURE, EconomyResponse.ResponseType.FAILURE,
e.getMessage() e.getMessage());
);
} }
return new EconomyResponse( return new EconomyResponse(
amount, amount,
bigDecimalToDouble(user.getBalance(currency)), bigDecimalToDouble(user.getBalance(currency)),
EconomyResponse.ResponseType.SUCCESS, EconomyResponse.ResponseType.SUCCESS,
"" "");
);
} }
@Override @Override

View file

@ -1,7 +1,9 @@
package dev.xhyrom.lighteco.currency.money.paper.hooks.vault; package dev.xhyrom.lighteco.currency.money.paper.hooks.vault;
import dev.xhyrom.lighteco.currency.money.paper.PaperMCLoader; import dev.xhyrom.lighteco.currency.money.paper.PaperMCLoader;
import net.milkbowl.vault.economy.Economy; import net.milkbowl.vault.economy.Economy;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.plugin.ServicePriority; import org.bukkit.plugin.ServicePriority;
import org.bukkit.plugin.ServicesManager; import org.bukkit.plugin.ServicesManager;
@ -15,8 +17,7 @@ public class VaultFactory {
} }
public void hook() { public void hook() {
if (this.vault == null) if (this.vault == null) vault = new Vault(this.loader.getPlugin());
vault = new Vault(this.loader.getPlugin());
ServicesManager manager = Bukkit.getServicesManager(); ServicesManager manager = Bukkit.getServicesManager();
manager.register(Economy.class, vault, this.loader, ServicePriority.Highest); manager.register(Economy.class, vault, this.loader, ServicePriority.Highest);

View file

@ -1,14 +1,17 @@
package dev.xhyrom.lighteco.paper; package dev.xhyrom.lighteco.paper;
import dev.xhyrom.lighteco.paper.logger.PaperLogger;
import dev.xhyrom.lighteco.common.plugin.bootstrap.LightEcoBootstrap; import dev.xhyrom.lighteco.common.plugin.bootstrap.LightEcoBootstrap;
import dev.xhyrom.lighteco.common.plugin.bootstrap.LoaderBootstrap; import dev.xhyrom.lighteco.common.plugin.bootstrap.LoaderBootstrap;
import dev.xhyrom.lighteco.common.plugin.logger.PluginLogger; import dev.xhyrom.lighteco.common.plugin.logger.PluginLogger;
import dev.xhyrom.lighteco.common.plugin.scheduler.SchedulerAdapter; import dev.xhyrom.lighteco.common.plugin.scheduler.SchedulerAdapter;
import dev.xhyrom.lighteco.paper.logger.PaperLogger;
import lombok.Getter; import lombok.Getter;
import org.bukkit.OfflinePlayer;
import net.kyori.adventure.audience.Audience; import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
@ -25,10 +28,13 @@ public class PaperLightEcoBootstrap implements LightEcoBootstrap, LoaderBootstra
@Getter @Getter
private final JavaPlugin loader; private final JavaPlugin loader;
@Getter @Getter
private final PluginLogger logger; private final PluginLogger logger;
@Getter @Getter
private final SchedulerAdapter scheduler; private final SchedulerAdapter scheduler;
@Getter @Getter
private BukkitAudiences audience; private BukkitAudiences audience;
@ -67,7 +73,8 @@ public class PaperLightEcoBootstrap implements LightEcoBootstrap, LoaderBootstra
@Override @Override
public Optional<UUID> lookupUniqueId(String username) { public Optional<UUID> lookupUniqueId(String username) {
return Optional.of(this.loader.getServer().getOfflinePlayer(username)).map(OfflinePlayer::getUniqueId); return Optional.of(this.loader.getServer().getOfflinePlayer(username))
.map(OfflinePlayer::getUniqueId);
} }
@Override @Override

View file

@ -3,16 +3,18 @@ package dev.xhyrom.lighteco.paper;
import dev.xhyrom.lighteco.api.LightEco; import dev.xhyrom.lighteco.api.LightEco;
import dev.xhyrom.lighteco.api.manager.ContextManager; import dev.xhyrom.lighteco.api.manager.ContextManager;
import dev.xhyrom.lighteco.api.platform.Platform; import dev.xhyrom.lighteco.api.platform.Platform;
import dev.xhyrom.lighteco.common.manager.currency.StandardCurrencyManager;
import dev.xhyrom.lighteco.common.manager.user.StandardUserManager;
import dev.xhyrom.lighteco.common.messaging.MessagingFactory;
import dev.xhyrom.lighteco.common.plugin.AbstractLightEcoPlugin;
import dev.xhyrom.lighteco.paper.hooks.Hooks; import dev.xhyrom.lighteco.paper.hooks.Hooks;
import dev.xhyrom.lighteco.paper.listeners.PaperCommandSuggestionsListener; import dev.xhyrom.lighteco.paper.listeners.PaperCommandSuggestionsListener;
import dev.xhyrom.lighteco.paper.listeners.PaperConnectionListener; import dev.xhyrom.lighteco.paper.listeners.PaperConnectionListener;
import dev.xhyrom.lighteco.paper.manager.PaperCommandManager; import dev.xhyrom.lighteco.paper.manager.PaperCommandManager;
import dev.xhyrom.lighteco.paper.manager.PaperContextManager; import dev.xhyrom.lighteco.paper.manager.PaperContextManager;
import dev.xhyrom.lighteco.common.manager.currency.StandardCurrencyManager;
import dev.xhyrom.lighteco.common.messaging.MessagingFactory;
import dev.xhyrom.lighteco.common.plugin.AbstractLightEcoPlugin;
import dev.xhyrom.lighteco.common.manager.user.StandardUserManager;
import lombok.Getter; import lombok.Getter;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.ServicePriority; import org.bukkit.plugin.ServicePriority;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
@ -23,10 +25,13 @@ public class PaperLightEcoPlugin extends AbstractLightEcoPlugin {
@Getter @Getter
private StandardUserManager userManager; private StandardUserManager userManager;
@Getter @Getter
private StandardCurrencyManager currencyManager; private StandardCurrencyManager currencyManager;
@Getter @Getter
private PaperCommandManager commandManager; private PaperCommandManager commandManager;
@Getter @Getter
private ContextManager<Player> contextManager; private ContextManager<Player> contextManager;
@ -36,8 +41,17 @@ public class PaperLightEcoPlugin extends AbstractLightEcoPlugin {
@Override @Override
protected void registerListeners() { protected void registerListeners() {
this.bootstrap.getLoader().getServer().getPluginManager().registerEvents(new PaperConnectionListener(this), this.bootstrap.getLoader()); this.bootstrap
this.bootstrap.getLoader().getServer().getPluginManager().registerEvents(new PaperCommandSuggestionsListener(this), this.bootstrap.getLoader()); .getLoader()
.getServer()
.getPluginManager()
.registerEvents(new PaperConnectionListener(this), this.bootstrap.getLoader());
this.bootstrap
.getLoader()
.getServer()
.getPluginManager()
.registerEvents(
new PaperCommandSuggestionsListener(this), this.bootstrap.getLoader());
} }
@Override @Override
@ -55,7 +69,15 @@ public class PaperLightEcoPlugin extends AbstractLightEcoPlugin {
@Override @Override
protected void registerApiOnPlatform(LightEco api) { protected void registerApiOnPlatform(LightEco api) {
this.getBootstrap().getLoader().getServer().getServicesManager().register(LightEco.class, api, this.getBootstrap().getLoader(), ServicePriority.Normal); this.getBootstrap()
.getLoader()
.getServer()
.getServicesManager()
.register(
LightEco.class,
api,
this.getBootstrap().getLoader(),
ServicePriority.Normal);
} }
@Override @Override

View file

@ -2,6 +2,7 @@ package dev.xhyrom.lighteco.paper;
import dev.xhyrom.lighteco.common.plugin.scheduler.SchedulerAdapter; import dev.xhyrom.lighteco.common.plugin.scheduler.SchedulerAdapter;
import dev.xhyrom.lighteco.common.plugin.scheduler.SchedulerTask; import dev.xhyrom.lighteco.common.plugin.scheduler.SchedulerTask;
import org.bukkit.scheduler.BukkitScheduler; import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.scheduler.BukkitTask; import org.bukkit.scheduler.BukkitTask;
@ -18,7 +19,8 @@ public class PaperSchedulerAdapter implements SchedulerAdapter {
this.bootstrap = bootstrap; this.bootstrap = bootstrap;
this.scheduler = bootstrap.getLoader().getServer().getScheduler(); this.scheduler = bootstrap.getLoader().getServer().getScheduler();
this.async = runnable -> this.scheduler.runTaskAsynchronously(this.bootstrap.getLoader(), runnable); this.async = runnable ->
this.scheduler.runTaskAsynchronously(this.bootstrap.getLoader(), runnable);
} }
public Executor async() { public Executor async() {
@ -27,29 +29,19 @@ public class PaperSchedulerAdapter implements SchedulerAdapter {
@Override @Override
public SchedulerTask asyncLater(Runnable runnable, long delay, TimeUnit unit) { public SchedulerTask asyncLater(Runnable runnable, long delay, TimeUnit unit) {
return new Task( return new Task(this.scheduler.runTaskLaterAsynchronously(
this.scheduler.runTaskLaterAsynchronously( this.bootstrap.getLoader(), runnable, unit.toSeconds(delay) * 20));
this.bootstrap.getLoader(),
runnable,
unit.toSeconds(delay) * 20
)
);
} }
@Override @Override
public SchedulerTask asyncRepeating(Runnable runnable, long interval, TimeUnit unit) { public SchedulerTask asyncRepeating(Runnable runnable, long interval, TimeUnit unit) {
return new Task( return new Task(this.scheduler.runTaskTimerAsynchronously(
this.scheduler.runTaskTimerAsynchronously( this.bootstrap.getLoader(), runnable, 0, unit.toSeconds(interval) * 20));
this.bootstrap.getLoader(),
runnable,
0,
unit.toSeconds(interval) * 20
)
);
} }
public class Task implements SchedulerTask { public class Task implements SchedulerTask {
private final BukkitTask task; private final BukkitTask task;
public Task(BukkitTask task) { public Task(BukkitTask task) {
this.task = task; this.task = task;
} }

View file

@ -1,7 +1,9 @@
package dev.xhyrom.lighteco.paper.chat; package dev.xhyrom.lighteco.paper.chat;
import dev.xhyrom.lighteco.common.model.chat.AbstractCommandSender; import dev.xhyrom.lighteco.common.model.chat.AbstractCommandSender;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;

View file

@ -1,7 +1,9 @@
package dev.xhyrom.lighteco.paper.hooks; package dev.xhyrom.lighteco.paper.hooks;
import dev.xhyrom.lighteco.paper.PaperLightEcoPlugin; import dev.xhyrom.lighteco.paper.PaperLightEcoPlugin;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@UtilityClass @UtilityClass

View file

@ -1,10 +1,13 @@
package dev.xhyrom.lighteco.paper.hooks; package dev.xhyrom.lighteco.paper.hooks;
import dev.xhyrom.lighteco.paper.PaperLightEcoPlugin;
import dev.xhyrom.lighteco.common.model.currency.Currency; import dev.xhyrom.lighteco.common.model.currency.Currency;
import dev.xhyrom.lighteco.common.model.user.User; import dev.xhyrom.lighteco.common.model.user.User;
import dev.xhyrom.lighteco.paper.PaperLightEcoPlugin;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
@ -20,7 +23,12 @@ public class PlaceholderAPIExpansion extends PlaceholderExpansion {
@Override @Override
public @NonNull String getAuthor() { public @NonNull String getAuthor() {
return this.plugin.getBootstrap().getLoader().getDescription().getAuthors().toString(); return this.plugin
.getBootstrap()
.getLoader()
.getDescription()
.getAuthors()
.toString();
} }
@Override @Override

View file

@ -3,10 +3,12 @@ package dev.xhyrom.lighteco.paper.listeners;
import com.destroystokyo.paper.event.brigadier.AsyncPlayerSendCommandsEvent; import com.destroystokyo.paper.event.brigadier.AsyncPlayerSendCommandsEvent;
import com.mojang.brigadier.tree.CommandNode; import com.mojang.brigadier.tree.CommandNode;
import com.mojang.brigadier.tree.LiteralCommandNode; import com.mojang.brigadier.tree.LiteralCommandNode;
import dev.xhyrom.lighteco.paper.PaperLightEcoPlugin;
import dev.xhyrom.lighteco.paper.util.PaperBrigadier;
import dev.xhyrom.lighteco.paper.chat.PaperCommandSender;
import dev.xhyrom.lighteco.common.command.CommandSource; import dev.xhyrom.lighteco.common.command.CommandSource;
import dev.xhyrom.lighteco.paper.PaperLightEcoPlugin;
import dev.xhyrom.lighteco.paper.chat.PaperCommandSender;
import dev.xhyrom.lighteco.paper.util.PaperBrigadier;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
@ -23,23 +25,37 @@ public class PaperCommandSuggestionsListener implements Listener {
PaperCommandSender sender = new PaperCommandSender(event.getPlayer()); PaperCommandSender sender = new PaperCommandSender(event.getPlayer());
CommandSource source = new CommandSource(this.plugin, sender); CommandSource source = new CommandSource(this.plugin, sender);
if (event.isAsynchronous() || !event.hasFiredAsync()) { if (event.isAsynchronous() || !event.hasFiredAsync()) {
for (CommandNode<CommandSource> command : this.plugin.getCommandManager().getDispatcher().getRoot().getChildren()) { for (CommandNode<CommandSource> command :
this.plugin.getCommandManager().getDispatcher().getRoot().getChildren()) {
PaperBrigadier.removeChild(event.getCommandNode(), command.getName()); PaperBrigadier.removeChild(event.getCommandNode(), command.getName());
PaperBrigadier.removeChild(event.getCommandNode(), this.plugin.getBootstrap().getLoader().getName().toLowerCase() + ":" + command.getName()); PaperBrigadier.removeChild(
event.getCommandNode(),
this.plugin.getBootstrap().getLoader().getName().toLowerCase() + ":"
+ command.getName());
if (!command.canUse(source)) continue; if (!command.canUse(source)) continue;
addChild(event, source, command, createClone(command)); addChild(event, source, command, createClone(command));
addChild(event, source, command, createClone(this.plugin.getBootstrap().getLoader().getName().toLowerCase() + ":" + command.getName(), command)); addChild(
event,
source,
command,
createClone(
this.plugin.getBootstrap().getLoader().getName().toLowerCase() + ":"
+ command.getName(),
command));
} }
} }
} }
@SuppressWarnings({"rawtypes", "unchecked", "deprecation"}) @SuppressWarnings({"rawtypes", "unchecked", "deprecation"})
private void addChild(AsyncPlayerSendCommandsEvent<?> event, CommandSource source, CommandNode<CommandSource> command, CommandNode<CommandSource> clone) { private void addChild(
AsyncPlayerSendCommandsEvent<?> event,
CommandSource source,
CommandNode<CommandSource> command,
CommandNode<CommandSource> clone) {
for (CommandNode<CommandSource> child : command.getChildren()) { for (CommandNode<CommandSource> child : command.getChildren()) {
if (child.canUse(source)) if (child.canUse(source)) clone.addChild(child);
clone.addChild(child);
} }
event.getCommandNode().addChild((CommandNode) clone); event.getCommandNode().addChild((CommandNode) clone);
@ -49,7 +65,14 @@ public class PaperCommandSuggestionsListener implements Listener {
return createClone(command.getName(), command); return createClone(command.getName(), command);
} }
private CommandNode<CommandSource> createClone(String name, CommandNode<CommandSource> command) { private CommandNode<CommandSource> createClone(
return new LiteralCommandNode<>(name, command.getCommand(), command.getRequirement(), command.getRedirect(), command.getRedirectModifier(), command.isFork()); String name, CommandNode<CommandSource> command) {
return new LiteralCommandNode<>(
name,
command.getCommand(),
command.getRequirement(),
command.getRedirect(),
command.getRedirectModifier(),
command.isFork());
} }
} }

View file

@ -1,11 +1,13 @@
package dev.xhyrom.lighteco.paper.listeners; package dev.xhyrom.lighteco.paper.listeners;
import dev.xhyrom.lighteco.paper.PaperLightEcoPlugin;
import dev.xhyrom.lighteco.common.model.currency.Currency; import dev.xhyrom.lighteco.common.model.currency.Currency;
import dev.xhyrom.lighteco.common.model.user.User; import dev.xhyrom.lighteco.common.model.user.User;
import dev.xhyrom.lighteco.paper.PaperLightEcoPlugin;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
@ -29,21 +31,24 @@ public class PaperConnectionListener implements Listener {
} }
try { try {
this.plugin.getStorage().loadUser(event.getUniqueId(), event.getName()).join(); this.plugin
.getStorage()
.loadUser(event.getUniqueId(), event.getName())
.join();
} catch (Exception e) { } catch (Exception e) {
this.plugin.getBootstrap().getLogger() this.plugin
.error("Failed to load user data for %s (%s)", e, event.getName(), event.getUniqueId()); .getBootstrap()
.getLogger()
.error(
"Failed to load user data for %s (%s)",
e, event.getName(), event.getUniqueId());
Component reason = miniMessage.deserialize( Component reason = miniMessage.deserialize(
"<bold>LightEco</bold> <red>Failed to load your data. Contact a staff member for assistance." "<bold>LightEco</bold> <red>Failed to load your data. Contact a staff member for assistance.");
);
event.disallow( event.disallow(
AsyncPlayerPreLoginEvent.Result.KICK_OTHER, AsyncPlayerPreLoginEvent.Result.KICK_OTHER,
LegacyComponentSerializer.legacySection().serialize( LegacyComponentSerializer.legacySection().serialize(reason));
reason
)
);
} }
} }
@ -57,9 +62,11 @@ public class PaperConnectionListener implements Listener {
return; return;
} }
this.plugin.getUserManager().saveUser(user) this.plugin.getUserManager().saveUser(user).thenAccept(v -> this.plugin
.thenAccept(v -> this.plugin.getMessagingService().ifPresent(service -> { .getMessagingService()
for (Currency currency : this.plugin.getCurrencyManager().getRegisteredCurrencies()) { .ifPresent(service -> {
for (Currency currency :
this.plugin.getCurrencyManager().getRegisteredCurrencies()) {
service.pushUserUpdate(user, currency); service.pushUserUpdate(user, currency);
} }
})); }));

View file

@ -1,13 +1,14 @@
package dev.xhyrom.lighteco.paper.manager; package dev.xhyrom.lighteco.paper.manager;
import com.mojang.brigadier.ParseResults; import com.mojang.brigadier.ParseResults;
import dev.xhyrom.lighteco.paper.chat.PaperCommandSender;
import dev.xhyrom.lighteco.common.command.CommandManager; import dev.xhyrom.lighteco.common.command.CommandManager;
import dev.xhyrom.lighteco.common.command.CommandSource; import dev.xhyrom.lighteco.common.command.CommandSource;
import dev.xhyrom.lighteco.common.command.abstraction.Command; import dev.xhyrom.lighteco.common.command.abstraction.Command;
import dev.xhyrom.lighteco.common.model.currency.Currency;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import dev.xhyrom.lighteco.paper.chat.PaperCommandSender;
import dev.xhyrom.lighteco.paper.util.PaperCommandMapUtil; import dev.xhyrom.lighteco.paper.util.PaperCommandMapUtil;
import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandExecutor;
import org.bukkit.command.TabCompleter; import org.bukkit.command.TabCompleter;
@ -37,28 +38,27 @@ public class PaperCommandManager extends CommandManager {
}; };
TabCompleter completer = (sender, bukkitCommand, s, args) -> { TabCompleter completer = (sender, bukkitCommand, s, args) -> {
final List<String> suggestions = new ArrayList<>(); final List<String> suggestions = new ArrayList<>();
final CommandSource source = new CommandSource(plugin, new PaperCommandSender(sender)); final CommandSource source = new CommandSource(plugin, new PaperCommandSender(sender));
final ParseResults<CommandSource> parseResults = getDispatcher().parse( final ParseResults<CommandSource> parseResults = getDispatcher()
command.getName() + (args.length > 0 ? " " + String.join(" ", args) : ""), .parse(
source command.getName()
); + (args.length > 0 ? " " + String.join(" ", args) : ""),
source);
getDispatcher().getCompletionSuggestions( getDispatcher()
parseResults .getCompletionSuggestions(parseResults)
).join().getList().forEach(suggestion -> suggestions.add(suggestion.getText())); .join()
.getList()
.forEach(suggestion -> suggestions.add(suggestion.getText()));
return suggestions; return suggestions;
}; };
List<String> aliases = new ArrayList<>(command.getAliases()); List<String> aliases = new ArrayList<>(command.getAliases());
aliases.add(command.getName()); aliases.add(command.getName());
this.commandMapUtil.register( this.commandMapUtil.register(executor, completer, aliases);
executor,
completer,
aliases
);
} }
} }

View file

@ -1,6 +1,7 @@
package dev.xhyrom.lighteco.paper.manager; package dev.xhyrom.lighteco.paper.manager;
import dev.xhyrom.lighteco.api.manager.ContextManager; import dev.xhyrom.lighteco.api.manager.ContextManager;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;

View file

@ -17,7 +17,7 @@ public class PaperBrigadier {
CHILDREN_FIELD = CommandNode.class.getDeclaredField("children"); CHILDREN_FIELD = CommandNode.class.getDeclaredField("children");
LITERALS_FIELD = CommandNode.class.getDeclaredField("literals"); LITERALS_FIELD = CommandNode.class.getDeclaredField("literals");
ARGUMENTS_FIELD = CommandNode.class.getDeclaredField("arguments"); ARGUMENTS_FIELD = CommandNode.class.getDeclaredField("arguments");
CHILDREN_FIELDS = new Field[]{CHILDREN_FIELD, LITERALS_FIELD, ARGUMENTS_FIELD}; CHILDREN_FIELDS = new Field[] {CHILDREN_FIELD, LITERALS_FIELD, ARGUMENTS_FIELD};
for (Field field : CHILDREN_FIELDS) { for (Field field : CHILDREN_FIELDS) {
field.setAccessible(true); field.setAccessible(true);

Some files were not shown because too many files have changed in this diff Show more