mirror of
https://github.com/Artillex-Studios/AxMinions.git
synced 2025-03-11 13:09:50 +01:00
Add reloading
This commit is contained in:
parent
ea55ef432b
commit
c8a6d01b0b
@ -76,7 +76,9 @@ public final class AxMinionsPlugin extends AxPlugin {
|
||||
|
||||
DataHandler.setup().thenRun(() -> LogUtils.debug("Loaded database!"));
|
||||
|
||||
this.reload();
|
||||
Language.reload();
|
||||
Skins.reload();
|
||||
Minions.reload();
|
||||
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
MinionWorldCache.loadArea(world);
|
||||
@ -124,12 +126,4 @@ public final class AxMinionsPlugin extends AxPlugin {
|
||||
AsyncUtils.stop();
|
||||
DatabaseConnector.getInstance().close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
Config.reload();
|
||||
Language.reload();
|
||||
Skins.reload();
|
||||
Minions.reload();
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import com.artillexstudios.axminions.config.Config;
|
||||
import com.artillexstudios.axminions.config.Language;
|
||||
import com.artillexstudios.axminions.config.Minions;
|
||||
import com.artillexstudios.axminions.config.Skins;
|
||||
import com.artillexstudios.axminions.database.DataHandler;
|
||||
import com.artillexstudios.axminions.minions.Level;
|
||||
import com.artillexstudios.axminions.minions.Minion;
|
||||
import com.artillexstudios.axminions.minions.MinionArea;
|
||||
@ -18,6 +19,7 @@ import com.artillexstudios.axminions.minions.MinionWorldCache;
|
||||
import com.artillexstudios.axminions.utils.Direction;
|
||||
import com.artillexstudios.axminions.utils.FileUtils;
|
||||
import com.artillexstudios.axminions.utils.LocationUtils;
|
||||
import com.artillexstudios.axminions.utils.LogUtils;
|
||||
import dev.jorel.commandapi.CommandTree;
|
||||
import dev.jorel.commandapi.arguments.IntegerArgument;
|
||||
import dev.jorel.commandapi.arguments.LiteralArgument;
|
||||
@ -26,6 +28,7 @@ import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@ -34,6 +37,8 @@ import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public final class AxMinionsCommand {
|
||||
|
||||
@ -75,6 +80,10 @@ public final class AxMinionsCommand {
|
||||
long start = System.nanoTime();
|
||||
List<File> failed = new ArrayList<>();
|
||||
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
MinionWorldCache.clear(world);
|
||||
}
|
||||
|
||||
if (!Config.reload()) {
|
||||
failed.add(FileUtils.PLUGIN_DIRECTORY.resolve("config.yml").toFile());
|
||||
}
|
||||
@ -89,15 +98,31 @@ public final class AxMinionsCommand {
|
||||
|
||||
Minions.reload();
|
||||
failed.addAll(Minions.failedToLoad());
|
||||
// TODO: refresh minions
|
||||
if (failed.isEmpty()) {
|
||||
MessageUtils.sendMessage(sender, Language.PREFIX, Language.RELOAD_SUCCESS, Placeholder.parsed("time", Long.toString((System.nanoTime() - start) / 1_000_000)));
|
||||
} else {
|
||||
MessageUtils.sendMessage(sender, Language.PREFIX, Language.RELOAD_FAIL, Placeholder.parsed("time", Long.toString((System.nanoTime() - start) / 1_000_000)), Placeholder.parsed("files", String.join(", ", failed.stream()
|
||||
.map(File::getName)
|
||||
.toList())
|
||||
));
|
||||
}
|
||||
|
||||
CompletableFuture<?>[] futures = Minions.loadingMinions().toArray(new CompletableFuture[0]);
|
||||
List<World> worlds = Bukkit.getWorlds();
|
||||
AtomicInteger counter = new AtomicInteger();
|
||||
CompletableFuture.allOf(futures).thenRun(() -> {
|
||||
Minions.loadingMinions().clear();
|
||||
|
||||
for (World world : worlds) {
|
||||
DataHandler.loadMinions(world).toCompletableFuture().thenAccept(loaded -> {
|
||||
LogUtils.debug("Loaded {} minions in world {} in {} ms!", loaded.firstInt(), world.getName(), loaded.secondLong() / 1_000_000);
|
||||
if (counter.incrementAndGet() != futures.length * worlds.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (failed.isEmpty()) {
|
||||
MessageUtils.sendMessage(sender, Language.PREFIX, Language.RELOAD_SUCCESS, Placeholder.parsed("time", Long.toString((System.nanoTime() - start) / 1_000_000)));
|
||||
} else {
|
||||
MessageUtils.sendMessage(sender, Language.PREFIX, Language.RELOAD_FAIL, Placeholder.parsed("time", Long.toString((System.nanoTime() - start) / 1_000_000)), Placeholder.parsed("files", String.join(", ", failed.stream()
|
||||
.map(File::getName)
|
||||
.toList())
|
||||
));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
)
|
||||
.then(new LiteralArgument("debug")
|
||||
|
@ -13,12 +13,13 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
public final class Minions {
|
||||
private static final Minions INSTANCE = new Minions();
|
||||
private final File minionsDirectory = com.artillexstudios.axminions.utils.FileUtils.PLUGIN_DIRECTORY.resolve("minions").toFile();
|
||||
private final ObjectArrayList<File> failedToLoad = new ObjectArrayList<>();
|
||||
private final ObjectArrayList<CompletableFuture<Void>> loadingMinions = new ObjectArrayList<>();
|
||||
private final ConcurrentLinkedQueue<CompletableFuture<Void>> loadingMinions = new ConcurrentLinkedQueue<>();
|
||||
private final List<File> failedToLoadImmutable = Collections.unmodifiableList(failedToLoad);
|
||||
|
||||
public static void reload() {
|
||||
@ -61,7 +62,7 @@ public final class Minions {
|
||||
}
|
||||
}
|
||||
|
||||
public static ObjectArrayList<CompletableFuture<Void>> loadingMinions() {
|
||||
public static ConcurrentLinkedQueue<CompletableFuture<Void>> loadingMinions() {
|
||||
return INSTANCE.loadingMinions;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.artillexstudios.axminions.listeners;
|
||||
|
||||
import com.artillexstudios.axminions.minions.MinionArea;
|
||||
import com.artillexstudios.axminions.minions.MinionWorldCache;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
@ -16,10 +15,7 @@ public final class WorldListener implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onWorldUnloadEvent(WorldUnloadEvent event) {
|
||||
MinionArea area = MinionWorldCache.remove(event.getWorld());
|
||||
|
||||
if (area != null) {
|
||||
// TODO: Remove all minions from the area
|
||||
}
|
||||
MinionWorldCache.clear(event.getWorld());
|
||||
MinionWorldCache.remove(event.getWorld());
|
||||
}
|
||||
}
|
||||
|
@ -142,7 +142,13 @@ public final class Minion {
|
||||
this.entity.spawn();
|
||||
}
|
||||
|
||||
// Remove removes the minion from the database,
|
||||
// while destroy removes the minion from the world
|
||||
public void remove() {
|
||||
this.destroy();
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
this.entity.remove();
|
||||
}
|
||||
|
||||
|
@ -227,6 +227,24 @@ public final class MinionArea {
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.writeLock.lock();
|
||||
try {
|
||||
this.writeCount++;
|
||||
// Load the list into stack memory for faster access
|
||||
ObjectArrayList<ChunkPos> positions = this.positions;
|
||||
|
||||
// We don't want to reevaluate the size of the list
|
||||
int size = positions.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
ChunkPos pos = positions.get(i);
|
||||
pos.minions().clear();
|
||||
}
|
||||
} finally {
|
||||
this.writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public long readCount() {
|
||||
return this.readCount;
|
||||
}
|
||||
|
@ -33,7 +33,9 @@ public final class MinionSaver {
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
this.future.cancel(false);
|
||||
this.future = null;
|
||||
if (this.future != null && !this.future.isCancelled()) {
|
||||
this.future.cancel(false);
|
||||
this.future = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,12 +23,22 @@ public final class MinionWorldCache {
|
||||
public static void add(Minion minion) {
|
||||
minions.add(minion);
|
||||
MinionArea area = worlds.get(minion.location().getWorld());
|
||||
if (area == null) {
|
||||
LogUtils.error("Tried to add minion to unknown world! {}", minion);
|
||||
return;
|
||||
}
|
||||
|
||||
area.load(minion);
|
||||
}
|
||||
|
||||
public static void remove(Minion minion) {
|
||||
minions.remove(minion);
|
||||
MinionArea area = worlds.get(minion.location().getWorld());
|
||||
if (area == null) {
|
||||
LogUtils.error("Tried to remove minion from unknown world! {}", minion);
|
||||
return;
|
||||
}
|
||||
|
||||
area.remove(minion);
|
||||
}
|
||||
|
||||
@ -40,6 +50,23 @@ public final class MinionWorldCache {
|
||||
return worlds.remove(world);
|
||||
}
|
||||
|
||||
public static void clear(World world) {
|
||||
LogUtils.debug("Worlds map pre clear: {}", worlds);
|
||||
MinionArea area = getArea(world);
|
||||
if (area == null) {
|
||||
LogUtils.error("Tried to remove minion from unknown world {}! Map: {}", world.getName(), worlds);
|
||||
return;
|
||||
}
|
||||
|
||||
area.forEachPos(position -> {
|
||||
for (Minion minion : position.minions()) {
|
||||
minion.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
area.clear();
|
||||
}
|
||||
|
||||
public static ObjectArrayList<Minion> minions() {
|
||||
return minions;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user