Update Sponge8 implementation with some small improvements

This commit is contained in:
Blue (Lukas Rieger) 2021-05-16 21:00:54 +02:00
parent 34d1144717
commit 445b18cd65
No known key found for this signature in database
GPG Key ID: 904C4995F9E1F800
7 changed files with 133 additions and 188 deletions

View File

@ -24,21 +24,16 @@
*/ */
package de.bluecolored.bluemap.sponge; package de.bluecolored.bluemap.sponge;
import java.io.File; import de.bluecolored.bluemap.common.plugin.Plugin;
import java.io.IOException; import de.bluecolored.bluemap.common.plugin.serverinterface.Player;
import java.nio.file.Path; import de.bluecolored.bluemap.common.plugin.serverinterface.ServerEventListener;
import java.util.ArrayList; import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface;
import java.util.Collection; import de.bluecolored.bluemap.core.MinecraftVersion;
import java.util.Collections; import de.bluecolored.bluemap.core.logger.Logger;
import java.util.List; import de.bluecolored.bluemap.core.resourcepack.ParseResourceException;
import java.util.Map; import de.bluecolored.bluemap.sponge.SpongeCommands.SpongeCommandProxy;
import java.util.Optional; import net.querz.nbt.CompoundTag;
import java.util.UUID; import net.querz.nbt.NBTUtil;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import javax.inject.Inject;
import org.bstats.sponge.MetricsLite2; import org.bstats.sponge.MetricsLite2;
import org.spongepowered.api.Sponge; import org.spongepowered.api.Sponge;
import org.spongepowered.api.config.ConfigDir; import org.spongepowered.api.config.ConfigDir;
@ -54,16 +49,13 @@
import org.spongepowered.api.world.World; import org.spongepowered.api.world.World;
import org.spongepowered.api.world.storage.WorldProperties; import org.spongepowered.api.world.storage.WorldProperties;
import de.bluecolored.bluemap.common.plugin.Plugin; import javax.inject.Inject;
import de.bluecolored.bluemap.common.plugin.serverinterface.Player; import java.io.File;
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerEventListener; import java.io.IOException;
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface; import java.nio.file.Path;
import de.bluecolored.bluemap.core.MinecraftVersion; import java.util.*;
import de.bluecolored.bluemap.core.logger.Logger; import java.util.concurrent.ConcurrentHashMap;
import de.bluecolored.bluemap.core.resourcepack.ParseResourceException; import java.util.concurrent.ExecutionException;
import de.bluecolored.bluemap.sponge.SpongeCommands.SpongeCommandProxy;
import net.querz.nbt.CompoundTag;
import net.querz.nbt.NBTUtil;
@org.spongepowered.api.plugin.Plugin ( @org.spongepowered.api.plugin.Plugin (
id = Plugin.PLUGIN_ID, id = Plugin.PLUGIN_ID,
@ -81,15 +73,15 @@ public class SpongePlugin implements ServerInterface {
@SuppressWarnings("unused") @SuppressWarnings("unused")
private MetricsLite2 metrics; private MetricsLite2 metrics;
private Plugin pluginInstance; private final Plugin pluginInstance;
private SpongeCommands commands; private final SpongeCommands commands;
private SpongeExecutorService asyncExecutor; private SpongeExecutorService asyncExecutor;
private SpongeExecutorService syncExecutor; private SpongeExecutorService syncExecutor;
private int playerUpdateIndex = 0; private int playerUpdateIndex = 0;
private Map<UUID, Player> onlinePlayerMap; private final Map<UUID, Player> onlinePlayerMap;
private List<SpongePlayer> onlinePlayerList; private final List<SpongePlayer> onlinePlayerList;
@Inject @Inject
public SpongePlugin(org.slf4j.Logger logger) { public SpongePlugin(org.slf4j.Logger logger) {
@ -145,7 +137,7 @@ public void onServerStart(GameStartingServerEvent evt) {
@Listener @Listener
public void onServerStop(GameStoppingEvent evt) { public void onServerStop(GameStoppingEvent evt) {
Logger.global.logInfo("Stopping..."); Logger.global.logInfo("Stopping...");
Sponge.getScheduler().getScheduledTasks(this).forEach(t -> t.cancel()); Sponge.getScheduler().getScheduledTasks(this).forEach(Task::cancel);
pluginInstance.unload(); pluginInstance.unload();
Logger.global.logInfo("Saved and stopped!"); Logger.global.logInfo("Saved and stopped!");
} }
@ -207,9 +199,7 @@ public UUID getUUIDForWorld(File worldFolder) throws IOException {
@Override @Override
public String getWorldName(UUID worldUUID) { public String getWorldName(UUID worldUUID) {
Optional<World> world = Sponge.getServer().getWorld(worldUUID); Optional<World> world = Sponge.getServer().getWorld(worldUUID);
if (world.isPresent()) return world.get().getName(); return world.map(World::getName).orElse(null);
return null;
} }
@Override @Override
@ -233,7 +223,7 @@ public boolean isMetricsEnabled(boolean configValue) {
if (pluginContainer != null) { if (pluginContainer != null) {
Tristate metricsEnabled = Sponge.getMetricsConfigManager().getCollectionState(pluginContainer); Tristate metricsEnabled = Sponge.getMetricsConfigManager().getCollectionState(pluginContainer);
if (metricsEnabled != Tristate.UNDEFINED) { if (metricsEnabled != Tristate.UNDEFINED) {
return metricsEnabled == Tristate.TRUE ? true : false; return metricsEnabled == Tristate.TRUE;
} }
} }

View File

@ -1,9 +1,9 @@
dependencies { dependencies {
shadow "org.spongepowered:spongeapi:8.0.0-SNAPSHOT" shadow "org.spongepowered:spongeapi:8.0.0-SNAPSHOT"
compile group: 'org.bstats', name: 'bstats-sponge-lite', version: '1.5' implementation group: 'org.bstats', name: 'bstats-sponge-lite', version: '1.5'
compile (project(':BlueMapCommon')) { implementation (project(':BlueMapCommon')) {
//exclude dependencies provided by sponge //exclude dependencies provided by sponge
exclude group: 'com.google.guava', module: 'guava' exclude group: 'com.google.guava', module: 'guava'
exclude group: 'com.google.code.gson', module: 'gson' exclude group: 'com.google.code.gson', module: 'gson'
@ -13,9 +13,10 @@ dependencies {
} }
} }
build.dependsOn shadowJar { build.dependsOn shadowJar {
destinationDirectory = file '../../build/release' destinationDirectory = file '../../build/release'
archiveFileName = "BlueMap-${version}-sponge-8.0.0.jar" archiveFileName.set("BlueMap-${archiveVersion.get()}-sponge-8.0.0.jar")
relocate 'net.querz.nbt', 'de.bluecolored.shadow.querz.nbt' relocate 'net.querz.nbt', 'de.bluecolored.shadow.querz.nbt'
relocate 'org.apache.commons.io', 'de.bluecolored.shadow.apache.commons.io' relocate 'org.apache.commons.io', 'de.bluecolored.shadow.apache.commons.io'
@ -27,11 +28,13 @@ build.dependsOn shadowJar {
relocate 'com.typesafe.config', 'de.bluecolored.shadow.typesafe.config' relocate 'com.typesafe.config', 'de.bluecolored.shadow.typesafe.config'
relocate 'org.checkerframework', 'de.bluecolored.shadow.checkerframework' relocate 'org.checkerframework', 'de.bluecolored.shadow.checkerframework'
relocate 'org.codehaus', 'de.bluecolored.shadow.codehaus' relocate 'org.codehaus', 'de.bluecolored.shadow.codehaus'
relocate 'io.leangen.geantyref', 'de.bluecolored.shadow.geantyref'
} }
processResources { processResources {
from(sourceSets.main.resources.srcDirs) { from(sourceSets.main.resources.srcDirs) {
include 'META-INF/plugins.json' include 'META-INF/plugins.json'
duplicatesStrategy = DuplicatesStrategy.WARN
expand ( expand (
version: project.version version: project.version

View File

@ -50,41 +50,6 @@ public EventForwarder(ServerEventListener listener) {
this.listener = listener; this.listener = listener;
} }
/* Use ChunkSaveToDisk as it is the preferred event to use and more reliable on the chunk actually saved to disk
@Listener(order = Order.POST)
public void onWorldSaveToDisk(SaveWorldEvent evt) {
listener.onWorldSaveToDisk(evt.getTargetWorld().getUniqueId());
}
*/
@Listener(order = Order.POST)
public void onChunkSaveToDisk(ChunkEvent.Save.Pre evt) {
ResourceKey worldKey = evt.chunkWorld();
Optional<ServerWorld> world = Sponge.server().worldManager().world(worldKey);
if (world.isPresent()) {
listener.onChunkSaveToDisk(world.get().uniqueId(), SpongePlugin.fromSpongePoweredVector(evt.targetChunk().chunkPosition().toVector2(true)));
}
}
@Listener(order = Order.POST)
public void onBlockChange(ChangeBlockEvent.All evt) {
for (Transaction<BlockSnapshot> tr : evt.transactions()) {
if(!tr.isValid()) continue;
Optional<ServerLocation> ow = tr.finalReplacement().location();
if (ow.isPresent()) {
listener.onBlockChange(ow.get().world().uniqueId(), SpongePlugin.fromSpongePoweredVector(ow.get().position().toInt()));
}
}
}
// TODO event missing in Sponge
// @Listener(order = Order.POST)
// public void onChunkFinishedGeneration(PopulateChunkEvent.Post evt) {
// Vector3i chunkPos = evt.getTargetChunk().getPosition();
// listener.onChunkFinishedGeneration(evt.getTargetChunk().getWorld().getUniqueId(), new Vector2i(chunkPos.getX(), chunkPos.getZ()));
// }
@Listener(order = Order.POST) @Listener(order = Order.POST)
public void onPlayerJoin(ServerSideConnectionEvent.Join evt) { public void onPlayerJoin(ServerSideConnectionEvent.Join evt) {
listener.onPlayerJoin(evt.player().uniqueId()); listener.onPlayerJoin(evt.player().uniqueId());

View File

@ -23,25 +23,23 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
package de.bluecolored.bluemap.sponge8; package de.bluecolored.bluemap.sponge8;
import java.util.Optional; import com.flowpowered.math.vector.Vector3d;
import de.bluecolored.bluemap.common.plugin.Plugin;
import de.bluecolored.bluemap.common.plugin.serverinterface.CommandSource;
import de.bluecolored.bluemap.common.plugin.text.Text;
import de.bluecolored.bluemap.core.world.World;
import net.kyori.adventure.audience.Audience; import net.kyori.adventure.audience.Audience;
import org.spongepowered.api.adventure.SpongeComponents; import org.spongepowered.api.adventure.SpongeComponents;
import org.spongepowered.api.service.permission.Subject; import org.spongepowered.api.service.permission.Subject;
import org.spongepowered.api.world.Locatable; import org.spongepowered.api.world.Locatable;
import com.flowpowered.math.vector.Vector3d; import java.util.Optional;
import de.bluecolored.bluemap.common.plugin.Plugin;
import de.bluecolored.bluemap.common.plugin.serverinterface.CommandSource;
import de.bluecolored.bluemap.common.plugin.text.Text;
import de.bluecolored.bluemap.core.world.World;
public class SpongeCommandSource implements CommandSource { public class SpongeCommandSource implements CommandSource {
private Plugin plugin; private final Plugin plugin;
private Audience audience; private final Audience audience;
private Subject subject; private final Subject subject;
public SpongeCommandSource(Plugin plugin, Audience audience, Subject subject) { public SpongeCommandSource(Plugin plugin, Audience audience, Subject subject) {
this.plugin = plugin; this.plugin = plugin;

View File

@ -24,48 +24,42 @@
*/ */
package de.bluecolored.bluemap.sponge8; package de.bluecolored.bluemap.sponge8;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.spongepowered.api.command.Command;
import org.spongepowered.api.command.CommandCause;
import org.spongepowered.api.command.CommandResult;
import org.spongepowered.api.command.parameter.ArgumentReader;
import org.spongepowered.api.service.permission.Subject;
import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.Message;
import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.suggestion.Suggestion; import com.mojang.brigadier.suggestion.Suggestion;
import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.tree.CommandNode; import com.mojang.brigadier.tree.CommandNode;
import de.bluecolored.bluemap.common.plugin.Plugin; import de.bluecolored.bluemap.common.plugin.Plugin;
import de.bluecolored.bluemap.common.plugin.commands.Commands; import de.bluecolored.bluemap.common.plugin.commands.Commands;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.spongepowered.api.command.Command;
import org.spongepowered.api.command.CommandCause;
import org.spongepowered.api.command.CommandCompletion;
import org.spongepowered.api.command.CommandResult;
import org.spongepowered.api.command.parameter.ArgumentReader;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class SpongeCommands { public class SpongeCommands {
private CommandDispatcher<Subject> dispatcher; private final CommandDispatcher<CommandCause> dispatcher;
public SpongeCommands(final Plugin plugin) { public SpongeCommands(final Plugin plugin) {
this.dispatcher = new CommandDispatcher<>(); this.dispatcher = new CommandDispatcher<>();
// register commands // register commands
// this assumes that every Subject will also be an Audience new Commands<>(plugin, dispatcher, cause -> new SpongeCommandSource(plugin, cause.audience(), cause.subject()));
new Commands<>(plugin, dispatcher, subject -> new SpongeCommandSource(plugin, (Audience) subject, subject));
} }
public Collection<SpongeCommandProxy> getRootCommands(){ public Collection<SpongeCommandProxy> getRootCommands(){
Collection<SpongeCommandProxy> rootCommands = new ArrayList<>(); Collection<SpongeCommandProxy> rootCommands = new ArrayList<>();
for (CommandNode<Subject> node : this.dispatcher.getRoot().getChildren()) { for (CommandNode<CommandCause> node : this.dispatcher.getRoot().getChildren()) {
rootCommands.add(new SpongeCommandProxy(node.getName())); rootCommands.add(new SpongeCommandProxy(node.getName()));
} }
@ -92,7 +86,7 @@ public CommandResult process(CommandCause cause, ArgumentReader.Mutable argument
} }
try { try {
return CommandResult.builder().result(dispatcher.execute(command, cause.subject())).build(); return CommandResult.builder().result(dispatcher.execute(command, cause)).build();
} catch (CommandSyntaxException ex) { } catch (CommandSyntaxException ex) {
cause.audience().sendMessage(Component.text(ex.getRawMessage().getString(), NamedTextColor.RED)); cause.audience().sendMessage(Component.text(ex.getRawMessage().getString(), NamedTextColor.RED));
@ -104,28 +98,34 @@ public CommandResult process(CommandCause cause, ArgumentReader.Mutable argument
} }
@Override @Override
public List<String> suggestions(CommandCause cause, ArgumentReader.Mutable arguments) { public List<CommandCompletion> complete(CommandCause cause, ArgumentReader.Mutable arguments) {
String command = label; String command = label;
if (!arguments.input().isEmpty()) { if (!arguments.input().isEmpty()) {
command += " " + arguments.input(); command += " " + arguments.input();
} }
List<String> completions = new ArrayList<>(); List<CommandCompletion> completions = new ArrayList<>();
try { try {
Suggestions suggestions = dispatcher.getCompletionSuggestions(dispatcher.parse(command, cause.subject())).get(100, TimeUnit.MILLISECONDS); Suggestions suggestions = dispatcher.getCompletionSuggestions(dispatcher.parse(command, cause)).get(100, TimeUnit.MILLISECONDS);
for (Suggestion suggestion : suggestions.getList()) { for (Suggestion suggestion : suggestions.getList()) {
String text = suggestion.getText(); String text = suggestion.getText();
if (text.indexOf(' ') == -1) { if (text.indexOf(' ') == -1) {
completions.add(text); Message tooltip = suggestion.getTooltip();
if (tooltip == null) {
completions.add(CommandCompletion.of(text));
} else {
completions.add(CommandCompletion.of(text, Component.text(tooltip.getString())));
}
} }
} }
} catch (InterruptedException ignore) { } catch (InterruptedException ignore) {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
} catch (ExecutionException | TimeoutException ignore) {} } catch (ExecutionException | TimeoutException ignore) {}
completions.sort(String::compareToIgnoreCase); completions.sort(Comparator.comparing(CommandCompletion::completion));
return completions; return completions;
} }
@ -146,11 +146,11 @@ public Optional<Component> extendedDescription(CommandCause cause) {
@Override @Override
public Component usage(CommandCause cause) { public Component usage(CommandCause cause) {
CommandNode<Subject> node = dispatcher.getRoot().getChild(label); CommandNode<CommandCause> node = dispatcher.getRoot().getChild(label);
if (node == null) return Component.text("/" + label); if (node == null) return Component.text("/" + label);
List<Component> lines = new ArrayList<>(); List<Component> lines = new ArrayList<>();
for (String usageString : dispatcher.getSmartUsage(node, cause.subject()).values()) { for (String usageString : dispatcher.getSmartUsage(node, cause).values()) {
lines.add(Component.text("/" + label + " ", NamedTextColor.WHITE).append(Component.text(usageString, NamedTextColor.GRAY))); lines.add(Component.text("/" + label + " ", NamedTextColor.WHITE).append(Component.text(usageString, NamedTextColor.GRAY)));
} }

View File

@ -24,25 +24,20 @@
*/ */
package de.bluecolored.bluemap.sponge8; package de.bluecolored.bluemap.sponge8;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import com.flowpowered.math.vector.Vector3d; import com.flowpowered.math.vector.Vector3d;
import de.bluecolored.bluemap.common.plugin.serverinterface.Gamemode;
import de.bluecolored.bluemap.common.plugin.serverinterface.Player;
import de.bluecolored.bluemap.common.plugin.text.Text;
import org.spongepowered.api.Sponge; import org.spongepowered.api.Sponge;
import org.spongepowered.api.data.Keys; import org.spongepowered.api.data.Keys;
import org.spongepowered.api.effect.potion.PotionEffect; import org.spongepowered.api.effect.potion.PotionEffect;
import org.spongepowered.api.effect.potion.PotionEffectTypes; import org.spongepowered.api.effect.potion.PotionEffectTypes;
import org.spongepowered.api.entity.living.player.gamemode.GameMode; import org.spongepowered.api.entity.living.player.gamemode.GameMode;
import org.spongepowered.api.entity.living.player.gamemode.GameModes; import org.spongepowered.api.entity.living.player.gamemode.GameModes;
import de.bluecolored.bluemap.common.plugin.serverinterface.Gamemode;
import de.bluecolored.bluemap.common.plugin.serverinterface.Player;
import de.bluecolored.bluemap.common.plugin.text.Text;
import org.spongepowered.api.entity.living.player.server.ServerPlayer; import org.spongepowered.api.entity.living.player.server.ServerPlayer;
import java.util.*;
public class SpongePlayer implements Player { public class SpongePlayer implements Player {
private static final Map<GameMode, Gamemode> GAMEMODE_MAP = new HashMap<>(5); private static final Map<GameMode, Gamemode> GAMEMODE_MAP = new HashMap<>(5);
@ -54,7 +49,7 @@ public class SpongePlayer implements Player {
GAMEMODE_MAP.put(GameModes.NOT_SET.get(), Gamemode.SURVIVAL); GAMEMODE_MAP.put(GameModes.NOT_SET.get(), Gamemode.SURVIVAL);
} }
private UUID uuid; private final UUID uuid;
private Text name; private Text name;
private UUID world; private UUID world;
private Vector3d position; private Vector3d position;

View File

@ -24,29 +24,21 @@
*/ */
package de.bluecolored.bluemap.sponge8; package de.bluecolored.bluemap.sponge8;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.flowpowered.math.vector.Vector2i; import com.flowpowered.math.vector.Vector2i;
import com.flowpowered.math.vector.Vector3d; import com.flowpowered.math.vector.Vector3d;
import com.flowpowered.math.vector.Vector3i; import com.flowpowered.math.vector.Vector3i;
import com.google.inject.Inject; import com.google.inject.Inject;
import de.bluecolored.bluemap.common.plugin.Plugin;
import de.bluecolored.bluemap.common.plugin.serverinterface.Player;
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerEventListener;
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface;
import de.bluecolored.bluemap.core.MinecraftVersion;
import de.bluecolored.bluemap.core.logger.Logger;
import de.bluecolored.bluemap.core.resourcepack.ParseResourceException;
import de.bluecolored.bluemap.sponge8.SpongeCommands.SpongeCommandProxy;
import net.querz.nbt.CompoundTag;
import net.querz.nbt.NBTUtil;
import org.spongepowered.api.Platform; import org.spongepowered.api.Platform;
import org.spongepowered.api.ResourceKey;
import org.spongepowered.api.Server; import org.spongepowered.api.Server;
import org.spongepowered.api.Sponge; import org.spongepowered.api.Sponge;
import org.spongepowered.api.adventure.SpongeComponents; import org.spongepowered.api.adventure.SpongeComponents;
@ -63,21 +55,21 @@
import org.spongepowered.api.util.Ticks; import org.spongepowered.api.util.Ticks;
import org.spongepowered.api.util.Tristate; import org.spongepowered.api.util.Tristate;
import org.spongepowered.api.world.server.ServerWorld; import org.spongepowered.api.world.server.ServerWorld;
import de.bluecolored.bluemap.common.plugin.Plugin;
import de.bluecolored.bluemap.common.plugin.serverinterface.Player;
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerEventListener;
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface;
import de.bluecolored.bluemap.core.MinecraftVersion;
import de.bluecolored.bluemap.core.logger.Logger;
import de.bluecolored.bluemap.core.resourcepack.ParseResourceException;
import de.bluecolored.bluemap.sponge8.SpongeCommands.SpongeCommandProxy;
import org.spongepowered.plugin.PluginContainer; import org.spongepowered.plugin.PluginContainer;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
@org.spongepowered.plugin.jvm.Plugin(Plugin.PLUGIN_ID) @org.spongepowered.plugin.jvm.Plugin(Plugin.PLUGIN_ID)
public class SpongePlugin implements ServerInterface { public class SpongePlugin implements ServerInterface {
private final PluginContainer pluginContainer; private final PluginContainer pluginContainer;
@Inject @Inject
@ConfigDir(sharedRoot = false) @ConfigDir(sharedRoot = false)
private Path configurationDir; private Path configurationDir;
@ -87,17 +79,15 @@ public class SpongePlugin implements ServerInterface {
// @SuppressWarnings("unused") // @SuppressWarnings("unused")
// private MetricsLite2 metrics; // private MetricsLite2 metrics;
private Plugin pluginInstance; private final Plugin pluginInstance;
private SpongeCommands commands; private final SpongeCommands commands;
private Map<File, UUID> worldUUIDs = new ConcurrentHashMap<>();
private ExecutorService asyncExecutor; private ExecutorService asyncExecutor;
private ExecutorService syncExecutor; private ExecutorService syncExecutor;
private int playerUpdateIndex = 0; private int playerUpdateIndex = 0;
private Map<UUID, Player> onlinePlayerMap; private final Map<UUID, Player> onlinePlayerMap;
private List<SpongePlayer> onlinePlayerList; private final List<SpongePlayer> onlinePlayerList;
@Inject @Inject
public SpongePlugin(org.apache.logging.log4j.Logger logger, PluginContainer pluginContainer) { public SpongePlugin(org.apache.logging.log4j.Logger logger, PluginContainer pluginContainer) {
@ -107,7 +97,7 @@ public SpongePlugin(org.apache.logging.log4j.Logger logger, PluginContainer plug
this.onlinePlayerMap = new ConcurrentHashMap<>(); this.onlinePlayerMap = new ConcurrentHashMap<>();
this.onlinePlayerList = Collections.synchronizedList(new ArrayList<>()); this.onlinePlayerList = Collections.synchronizedList(new ArrayList<>());
final String versionFromSponge = Sponge.platform().container(Platform.Component.GAME).getMetadata().getVersion(); final String versionFromSponge = Sponge.platform().container(Platform.Component.GAME).metadata().version();
MinecraftVersion version = MinecraftVersion.MC_1_16; MinecraftVersion version = MinecraftVersion.MC_1_16;
try { try {
version = MinecraftVersion.fromVersionString(versionFromSponge); version = MinecraftVersion.fromVersionString(versionFromSponge);
@ -156,7 +146,7 @@ public void onServerStart(StartedEngineEvent<Server> evt) {
@Listener @Listener
public void onServerStop(StoppingEngineEvent<Server> evt) { public void onServerStop(StoppingEngineEvent<Server> evt) {
Logger.global.logInfo("Stopping..."); Logger.global.logInfo("Stopping...");
evt.engine().scheduler().tasksByPlugin(pluginContainer).forEach(ScheduledTask::cancel); evt.engine().scheduler().tasks(pluginContainer).forEach(ScheduledTask::cancel);
pluginInstance.unload(); pluginInstance.unload();
Logger.global.logInfo("Saved and stopped!"); Logger.global.logInfo("Saved and stopped!");
} }
@ -204,39 +194,35 @@ public void unregisterAllListeners() {
@Override @Override
public UUID getUUIDForWorld(File worldFolder) throws IOException { public UUID getUUIDForWorld(File worldFolder) throws IOException {
// this logic derives the the world key from the folder structure try {
final Pattern customDimension = Pattern.compile(".+/dimensions/([a-z0-9_.-]+)/([a-z0-9._-]+)$".replace("/", File.separator)); CompoundTag levelSponge = (CompoundTag) NBTUtil.readTag(new File(worldFolder, "level.dat"));
final Matcher matcher = customDimension.matcher(worldFolder.toString()); CompoundTag spongeData = levelSponge.getCompoundTag("SpongeData");
final ResourceKey key; int[] uuidIntArray = spongeData.getIntArray("UUID");
if (matcher.matches()) { if (uuidIntArray.length != 4) throw new IOException("World-UUID is stored in a wrong format! Is the worlds level.dat corrupted?");
key = ResourceKey.of(matcher.group(1), matcher.group(2)); return intArrayToUuid(uuidIntArray);
} else if ("DIM-1".equals(worldFolder.getName())) { } catch (IOException | RuntimeException e) {
key = ResourceKey.minecraft("the_nether"); throw new IOException("Failed to read the worlds level.dat!", e);
} else if ("DIM1".equals(worldFolder.getName())) {
key = ResourceKey.minecraft("the_end");
} else {
// assume it's the main world
key = Sponge.server().worldManager().defaultWorld().key();
} }
return Sponge.server().worldManager().world(key)
.map(ServerWorld::uniqueId)
.orElse(null);
} }
@Override @Override
public String getWorldName(UUID worldUUID) { public String getWorldName(UUID worldUUID) {
return getServerWorld(worldUUID) return getServerWorld(worldUUID)
.map(serverWorld -> serverWorld .flatMap(
serverWorld -> serverWorld
.properties() .properties()
.displayName() .displayName()
.map(SpongeComponents.plainSerializer()::serialize) .map(SpongeComponents.plainSerializer()::serialize)
.orElse(serverWorld.key().asString())) )
.orElse(null); .orElse(null);
} }
private Optional<ServerWorld> getServerWorld(UUID worldUUID) { private Optional<ServerWorld> getServerWorld(UUID worldUUID) {
return Sponge.server().worldManager().worldKey(worldUUID).flatMap(k -> Sponge.server().worldManager().world(k)); for (ServerWorld world : Sponge.server().worldManager().worlds()) {
if (world.uniqueId().equals(worldUUID)) return Optional.of(world);
}
return Optional.empty();
} }
@Override @Override
@ -259,7 +245,7 @@ public boolean isMetricsEnabled(boolean configValue) {
if (pluginContainer != null) { if (pluginContainer != null) {
Tristate metricsEnabled = Sponge.metricsConfigManager().collectionState(pluginContainer); Tristate metricsEnabled = Sponge.metricsConfigManager().collectionState(pluginContainer);
if (metricsEnabled != Tristate.UNDEFINED) { if (metricsEnabled != Tristate.UNDEFINED) {
return metricsEnabled == Tristate.TRUE ? true : false; return metricsEnabled == Tristate.TRUE;
} }
} }
@ -309,15 +295,23 @@ private void updateSomePlayers() {
} }
public static Vector3d fromSpongePoweredVector(org.spongepowered.math.vector.Vector3d vec) { public static Vector3d fromSpongePoweredVector(org.spongepowered.math.vector.Vector3d vec) {
return new Vector3d(vec.getX(), vec.getY(), vec.getZ()); return new Vector3d(vec.x(), vec.y(), vec.z());
} }
public static Vector3i fromSpongePoweredVector(org.spongepowered.math.vector.Vector3i vec) { public static Vector3i fromSpongePoweredVector(org.spongepowered.math.vector.Vector3i vec) {
return new Vector3i(vec.getX(), vec.getY(), vec.getZ()); return new Vector3i(vec.x(), vec.y(), vec.z());
} }
public static Vector2i fromSpongePoweredVector(org.spongepowered.math.vector.Vector2i vec) { public static Vector2i fromSpongePoweredVector(org.spongepowered.math.vector.Vector2i vec) {
return new Vector2i(vec.getX(), vec.getY()); return new Vector2i(vec.x(), vec.y());
}
private static UUID intArrayToUuid(int[] array) {
if (array.length != 4) throw new IllegalArgumentException("Int array has to contain exactly 4 ints!");
return new UUID(
(long) array[0] << 32 | (long) array[1] & 0x00000000FFFFFFFFL,
(long) array[2] << 32 | (long) array[3] & 0x00000000FFFFFFFFL
);
} }
} }