1
0
Fork 0
mirror of https://github.com/xHyroM/lighteco.git synced 2024-11-21 22:41:06 +01:00

feat: task schedulers

This commit is contained in:
Jozef Steinhübl 2023-08-30 00:41:09 +02:00
parent 2cfba60fbe
commit 63dc921539
20 changed files with 165 additions and 42 deletions

View file

@ -4,6 +4,7 @@ import dev.xhyrom.lighteco.bukkit.logger.BukkitLogger;
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 lombok.Getter; import lombok.Getter;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
@ -49,6 +50,11 @@ public class BukkitLightEcoBootstrap implements LightEcoBootstrap, LoaderBootstr
return this.loader.getServer(); return this.loader.getServer();
} }
@Override
public SchedulerAdapter getScheduler() {
return new BukkitSchedulerAdapter(this);
}
@Override @Override
public Path getDataDirectory() { public Path getDataDirectory() {
return this.loader.getDataFolder().toPath(); return this.loader.getDataFolder().toPath();

View file

@ -0,0 +1,53 @@
package dev.xhyrom.lighteco.bukkit;
import dev.xhyrom.lighteco.common.plugin.scheduler.SchedulerAdapter;
import dev.xhyrom.lighteco.common.plugin.scheduler.SchedulerTask;
import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.scheduler.BukkitTask;
import java.util.concurrent.TimeUnit;
public class BukkitSchedulerAdapter implements SchedulerAdapter {
private final BukkitLightEcoBootstrap bootstrap;
private final BukkitScheduler scheduler;
public BukkitSchedulerAdapter(BukkitLightEcoBootstrap bootstrap) {
this.bootstrap = bootstrap;
this.scheduler = bootstrap.getServer().getScheduler();
}
@Override
public SchedulerTask asyncLater(Runnable runnable, long delay, TimeUnit unit) {
return new Task(
this.scheduler.runTaskLaterAsynchronously(
this.bootstrap.getLoader(),
runnable,
unit.toSeconds(delay) * 20
)
);
}
@Override
public SchedulerTask asyncRepeating(Runnable runnable, long interval, TimeUnit unit) {
return new Task(
this.scheduler.runTaskTimerAsynchronously(
this.bootstrap.getLoader(),
runnable,
0,
unit.toSeconds(interval) * 20
)
);
}
public class Task implements SchedulerTask {
private final BukkitTask task;
public Task(BukkitTask task) {
this.task = task;
}
@Override
public void cancel() {
this.task.cancel();
}
}
}

View file

@ -45,7 +45,7 @@ public class BalanceCommand implements Command {
} }
this.manager.plugin.getUserManager().loadUser(target.getUniqueId()) this.manager.plugin.getUserManager().loadUser(target.getUniqueId())
.thenAcceptAsync(result -> { .thenAccept(result -> {
String username = result.getUsername() == null ? String username = result.getUsername() == null ?
target.getName() != null target.getName() != null
? target.getName() ? target.getName()

View file

@ -44,7 +44,7 @@ public class GiveCommand implements Command {
if (!this.manager.canUse(sender, currency)) return; if (!this.manager.canUse(sender, currency)) return;
this.manager.plugin.getUserManager().loadUser(target.getUniqueId()) this.manager.plugin.getUserManager().loadUser(target.getUniqueId())
.thenAcceptAsync(result -> { .thenAccept(result -> {
String name = target.getName() != null ? target.getName() : args.getRaw("target"); String name = target.getName() != null ? target.getName() : args.getRaw("target");
result.setUsername(name); result.setUsername(name);

View file

@ -43,7 +43,7 @@ public class PayCommand implements Command {
if (!this.manager.canUse(sender, currency)) return; if (!this.manager.canUse(sender, currency)) return;
this.manager.plugin.getUserManager().loadUser(target.getUniqueId()) this.manager.plugin.getUserManager().loadUser(target.getUniqueId())
.thenAcceptAsync(result -> { .thenAccept(result -> {
String username = result.getUsername() == null ? String username = result.getUsername() == null ?
target.getName() != null target.getName() != null
? target.getName() ? target.getName()

View file

@ -44,7 +44,7 @@ public class SetCommand implements Command {
if (!this.manager.canUse(sender, currency)) return; if (!this.manager.canUse(sender, currency)) return;
this.manager.plugin.getUserManager().loadUser(target.getUniqueId()) this.manager.plugin.getUserManager().loadUser(target.getUniqueId())
.thenAcceptAsync(result -> { .thenAccept(result -> {
String name = target.getName() != null ? target.getName() : args.getRaw("target"); String name = target.getName() != null ? target.getName() : args.getRaw("target");
result.setUsername(name); result.setUsername(name);

View file

@ -44,7 +44,7 @@ public class TakeCommand implements Command {
if (!this.manager.canUse(sender, currency)) return; if (!this.manager.canUse(sender, currency)) return;
this.manager.plugin.getUserManager().loadUser(target.getUniqueId()) this.manager.plugin.getUserManager().loadUser(target.getUniqueId())
.thenAcceptAsync(result -> { .thenAccept(result -> {
String name = target.getName() != null ? target.getName() : args.getRaw("target"); String name = target.getName() != null ? target.getName() : args.getRaw("target");
result.setUsername(name); result.setUsername(name);

View file

@ -1,13 +1,17 @@
package dev.xhyrom.lighteco.bukkit.listeners; package dev.xhyrom.lighteco.bukkit.listeners;
import dev.xhyrom.lighteco.bukkit.BukkitLightEcoPlugin; import dev.xhyrom.lighteco.bukkit.BukkitLightEcoPlugin;
import dev.xhyrom.lighteco.common.model.user.User;
import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.MiniMessage;
import org.bukkit.Bukkit;
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;
import org.bukkit.event.player.AsyncPlayerPreLoginEvent; import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import java.util.UUID;
public class BukkitConnectionListener implements Listener { public class BukkitConnectionListener implements Listener {
private final BukkitLightEcoPlugin plugin; private final BukkitLightEcoPlugin plugin;
private final MiniMessage miniMessage = MiniMessage.miniMessage(); private final MiniMessage miniMessage = MiniMessage.miniMessage();
@ -34,7 +38,22 @@ public class BukkitConnectionListener implements Listener {
} }
} }
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) { public void onPlayerQuit(PlayerQuitEvent event) {
this.plugin.getUserManager().unload(event.getPlayer().getUniqueId()); UUID uniqueId = event.getPlayer().getUniqueId();
User user = this.plugin.getUserManager().getIfLoaded(uniqueId);
if (!user.isDirty()) {
this.plugin.getUserManager().unload(uniqueId);
return;
}
this.plugin.getUserManager().saveUser(user)
.thenAccept(v -> {
// make sure the player is offline before unloading
if (Bukkit.getPlayer(uniqueId) != null) return;
this.plugin.getUserManager().unload(uniqueId);
});
} }
} }

View file

@ -7,7 +7,6 @@ import dev.xhyrom.lighteco.api.model.user.User;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerChatEvent;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import java.util.List; import java.util.List;

View file

@ -112,8 +112,7 @@ public abstract class AbstractCommandManager implements CommandManager {
) )
); );
this.plugin.getUserManager().saveUser(target) removeFromMustWait(target.getUniqueId(), sender.getUniqueId());
.thenAccept(v -> removeFromMustWait(target.getUniqueId(), sender.getUniqueId()));
} }
@Override @Override
@ -133,8 +132,7 @@ public abstract class AbstractCommandManager implements CommandManager {
) )
); );
this.plugin.getUserManager().saveUser(target) removeFromMustWait(target.getUniqueId(), sender.getUniqueId());
.thenAccept(v -> removeFromMustWait(target.getUniqueId(), sender.getUniqueId()));
} }
@Override @Override
@ -154,8 +152,7 @@ public abstract class AbstractCommandManager implements CommandManager {
) )
); );
this.plugin.getUserManager().saveUser(target) removeFromMustWait(target.getUniqueId(), sender.getUniqueId());
.thenAccept(v -> removeFromMustWait(target.getUniqueId(), sender.getUniqueId()));
} }
@Override @Override
@ -209,7 +206,6 @@ public abstract class AbstractCommandManager implements CommandManager {
) )
); );
this.plugin.getUserManager().saveUsers(user, target) removeFromMustWait(target.getUniqueId(), sender.getUniqueId());
.thenAccept(v -> removeFromMustWait(sender.getUniqueId(), target.getUniqueId()));
} }
} }

View file

@ -5,6 +5,7 @@ import dev.xhyrom.lighteco.common.model.user.User;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;

View file

@ -3,6 +3,7 @@ package dev.xhyrom.lighteco.common.manager.user;
import dev.xhyrom.lighteco.common.manager.Manager; import dev.xhyrom.lighteco.common.manager.Manager;
import dev.xhyrom.lighteco.common.model.user.User; import dev.xhyrom.lighteco.common.model.user.User;
import java.util.Collection;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;

View file

@ -20,9 +20,14 @@ public class User {
@Getter @Getter
private final UUID uniqueId; private final UUID uniqueId;
@Getter
@Setter
private boolean dirty = false;
@Getter @Getter
@Setter @Setter
private String username; private String username;
private final HashMap<Currency, BigDecimal> balances = new HashMap<>(); private final HashMap<Currency, BigDecimal> balances = new HashMap<>();
public User(LightEcoPlugin plugin, UUID uniqueId) { public User(LightEcoPlugin plugin, UUID uniqueId) {
@ -46,6 +51,8 @@ public class User {
balance = balance.setScale(currency.fractionalDigits(), RoundingMode.DOWN); balance = balance.setScale(currency.fractionalDigits(), RoundingMode.DOWN);
balances.put(currency, balance); balances.put(currency, balance);
this.setDirty(true);
} }
public void deposit(@NonNull Currency currency, @NonNull BigDecimal amount) throws IllegalArgumentException { public void deposit(@NonNull Currency currency, @NonNull BigDecimal amount) throws IllegalArgumentException {
@ -53,7 +60,7 @@ public class User {
throw new IllegalArgumentException("Amount cannot be negative"); throw new IllegalArgumentException("Amount cannot be negative");
} }
setBalance(currency, getBalance(currency).add(amount)); this.setBalance(currency, this.getBalance(currency).add(amount));
} }
public void withdraw(@NonNull Currency currency, @NonNull BigDecimal amount) throws IllegalArgumentException { public void withdraw(@NonNull Currency currency, @NonNull BigDecimal amount) throws IllegalArgumentException {
@ -61,15 +68,11 @@ public class User {
throw new IllegalArgumentException("Amount cannot be negative"); throw new IllegalArgumentException("Amount cannot be negative");
} }
if (getBalance(currency).compareTo(amount) < 0) { if (this.getBalance(currency).compareTo(amount) < 0) {
// Withdraw all // Withdraw all
amount = getBalance(currency); amount = this.getBalance(currency);
} }
setBalance(currency, getBalance(currency).subtract(amount)); this.setBalance(currency, this.getBalance(currency).subtract(amount));
}
public void invalidateCaches() {
balances.clear();
} }
} }

View file

@ -8,10 +8,13 @@ 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.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 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.util.concurrent.TimeUnit;
@Getter @Getter
public abstract class AbstractLightEcoPlugin implements LightEcoPlugin { public abstract class AbstractLightEcoPlugin implements LightEcoPlugin {
private DependencyManager dependencyManager; private DependencyManager dependencyManager;
@ -51,6 +54,8 @@ public abstract class AbstractLightEcoPlugin implements LightEcoPlugin {
this.api = new LightEcoApi(this); this.api = new LightEcoApi(this);
LightEcoProvider.set(this.api); LightEcoProvider.set(this.api);
this.registerApiOnPlatform(this.api); this.registerApiOnPlatform(this.api);
this.getBootstrap().getScheduler().asyncRepeating(new UserSaveTask(this), 3, TimeUnit.SECONDS);
} }
public final void disable() { public final void disable() {

View file

@ -1,6 +1,7 @@
package dev.xhyrom.lighteco.common.plugin.bootstrap; 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 java.io.InputStream; import java.io.InputStream;
import java.nio.file.Path; import java.nio.file.Path;
@ -10,6 +11,7 @@ import java.util.UUID;
public interface LightEcoBootstrap { public interface LightEcoBootstrap {
Object getLoader(); Object getLoader();
PluginLogger getLogger(); PluginLogger getLogger();
SchedulerAdapter getScheduler();
Path getDataDirectory(); Path getDataDirectory();
List<UUID> getOnlinePlayers(); List<UUID> getOnlinePlayers();
InputStream getResourceStream(String filename); InputStream getResourceStream(String filename);

View file

@ -0,0 +1,9 @@
package dev.xhyrom.lighteco.common.plugin.scheduler;
import java.util.concurrent.TimeUnit;
public interface SchedulerAdapter {
SchedulerTask asyncLater(Runnable runnable, long delay, TimeUnit unit);
SchedulerTask asyncRepeating(Runnable runnable, long interval, TimeUnit unit);
}

View file

@ -0,0 +1,5 @@
package dev.xhyrom.lighteco.common.plugin.scheduler;
public interface SchedulerTask {
void cancel();
}

View file

@ -5,7 +5,6 @@ import dev.xhyrom.lighteco.api.storage.StorageProvider;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import dev.xhyrom.lighteco.common.util.ThrowableRunnable; import dev.xhyrom.lighteco.common.util.ThrowableRunnable;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;

View file

@ -0,0 +1,35 @@
package dev.xhyrom.lighteco.common.task;
import dev.xhyrom.lighteco.common.model.user.User;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import java.util.concurrent.ExecutionException;
public class UserSaveTask implements Runnable {
private final LightEcoPlugin plugin;
public UserSaveTask(LightEcoPlugin plugin) {
this.plugin = plugin;
}
@Override
public void run() {
User[] users = this.plugin.getUserManager().values().stream()
.filter(User::isDirty)
.toArray(User[]::new);
if (users.length == 0) {
return;
}
try {
this.plugin.getUserManager().saveUsers(users).get();
for (User user : users) {
user.setDirty(false);
}
} catch (InterruptedException | RuntimeException | ExecutionException e) {
this.plugin.getBootstrap().getLogger().error("Failed to save users", e);
}
}
}

View file

@ -7,12 +7,10 @@ import dev.xhyrom.lighteco.api.model.user.User;
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 org.jetbrains.annotations.NotNull;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ExecutionException;
public class Vault extends AbstractEconomy { public class Vault extends AbstractEconomy {
private final LightEco provider; private final LightEco provider;
@ -118,21 +116,8 @@ public class Vault extends AbstractEconomy {
); );
} }
return saveUser(amount, user); // Can happen on background
} this.provider.getUserManager().saveUser(user);
@NotNull
private EconomyResponse saveUser(double amount, User user) {
try {
provider.getUserManager().saveUser(user).get();
} catch (InterruptedException | ExecutionException e) {
return new EconomyResponse(
amount,
bigDecimalToDouble(user.getBalance(currency)),
EconomyResponse.ResponseType.FAILURE,
"Cannot save user"
);
}
return new EconomyResponse( return new EconomyResponse(
amount, amount,
@ -163,7 +148,12 @@ public class Vault extends AbstractEconomy {
); );
} }
return saveUser(amount, user); return new EconomyResponse(
amount,
bigDecimalToDouble(user.getBalance(currency)),
EconomyResponse.ResponseType.SUCCESS,
""
);
} }
@Override @Override