From ede84722fbfa396955de621fa14c74b879df0fc0 Mon Sep 17 00:00:00 2001 From: Phillip Schichtel Date: Sun, 4 Apr 2021 22:55:33 +0200 Subject: [PATCH] Port the plugin to sponge 8 --- implementations/sponge-8.0.0/build.gradle | 40 +++ .../bluemap/sponge8/EventForwarder.java | 103 ++++++ .../bluemap/sponge8/Log4J2Logger.java | 68 ++++ .../bluemap/sponge8/SpongeCommandSource.java | 80 +++++ .../bluemap/sponge8/SpongeCommands.java | 161 +++++++++ .../bluemap/sponge8/SpongePlayer.java | 143 ++++++++ .../bluemap/sponge8/SpongePlugin.java | 323 ++++++++++++++++++ .../src/main/resources/META-INF/plugins.json | 31 ++ .../de/bluecolored/bluemap/core-defaults.conf | 4 + .../de/bluecolored/bluemap/core.conf | 24 ++ .../bluecolored/bluemap/plugin-defaults.conf | 5 + .../de/bluecolored/bluemap/plugin.conf | 27 ++ .../bluecolored/bluemap/render-defaults.conf | 3 + .../de/bluecolored/bluemap/render.conf | 126 +++++++ .../bluemap/webserver-defaults.conf | 4 + .../de/bluecolored/bluemap/webserver.conf | 29 ++ settings.gradle | 2 + 17 files changed, 1173 insertions(+) create mode 100644 implementations/sponge-8.0.0/build.gradle create mode 100644 implementations/sponge-8.0.0/src/main/java/de/bluecolored/bluemap/sponge8/EventForwarder.java create mode 100644 implementations/sponge-8.0.0/src/main/java/de/bluecolored/bluemap/sponge8/Log4J2Logger.java create mode 100644 implementations/sponge-8.0.0/src/main/java/de/bluecolored/bluemap/sponge8/SpongeCommandSource.java create mode 100644 implementations/sponge-8.0.0/src/main/java/de/bluecolored/bluemap/sponge8/SpongeCommands.java create mode 100644 implementations/sponge-8.0.0/src/main/java/de/bluecolored/bluemap/sponge8/SpongePlayer.java create mode 100644 implementations/sponge-8.0.0/src/main/java/de/bluecolored/bluemap/sponge8/SpongePlugin.java create mode 100644 implementations/sponge-8.0.0/src/main/resources/META-INF/plugins.json create mode 100644 implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/core-defaults.conf create mode 100644 implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/core.conf create mode 100644 implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/plugin-defaults.conf create mode 100644 implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/plugin.conf create mode 100644 implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/render-defaults.conf create mode 100644 implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/render.conf create mode 100644 implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/webserver-defaults.conf create mode 100644 implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/webserver.conf diff --git a/implementations/sponge-8.0.0/build.gradle b/implementations/sponge-8.0.0/build.gradle new file mode 100644 index 00000000..1689d82c --- /dev/null +++ b/implementations/sponge-8.0.0/build.gradle @@ -0,0 +1,40 @@ +dependencies { + shadow "org.spongepowered:spongeapi:8.0.0-SNAPSHOT" + + compile group: 'org.bstats', name: 'bstats-sponge-lite', version: '1.5' + + compile (project(':BlueMapCommon')) { + //exclude dependencies provided by sponge + exclude group: 'com.google.guava', module: 'guava' + exclude group: 'com.google.code.gson', module: 'gson' + exclude group: 'org.apache.commons', module: 'commons-lang3' + exclude group: 'javax.inject' + exclude group: 'com.google.inject' + } +} + +build.dependsOn shadowJar { + destinationDirectory = file '../../build/release' + archiveFileName = "BlueMap-${version}-sponge-8.0.0.jar" + + relocate 'net.querz.nbt', 'de.bluecolored.shadow.querz.nbt' + relocate 'org.apache.commons.io', 'de.bluecolored.shadow.apache.commons.io' + relocate 'com.mojang.brigadier', 'de.bluecolored.shadow.mojang.brigadier' + relocate 'com.github.benmanes.caffeine', 'de.bluecolored.shadow.benmanes.caffeine' + relocate 'com.google.errorprone', 'de.bluecolored.shadow.google.errorprone' + relocate 'ninja.leaping.configurate', 'de.bluecolored.shadow.ninja.leaping.configurate' + relocate 'org.aopalliance', 'de.bluecolored.shadow.aopalliance' + relocate 'com.typesafe.config', 'de.bluecolored.shadow.typesafe.config' + relocate 'org.checkerframework', 'de.bluecolored.shadow.checkerframework' + relocate 'org.codehaus', 'de.bluecolored.shadow.codehaus' +} + +processResources { + from(sourceSets.main.resources.srcDirs) { + include 'META-INF/plugins.json' + + expand ( + version: project.version + ) + } +} diff --git a/implementations/sponge-8.0.0/src/main/java/de/bluecolored/bluemap/sponge8/EventForwarder.java b/implementations/sponge-8.0.0/src/main/java/de/bluecolored/bluemap/sponge8/EventForwarder.java new file mode 100644 index 00000000..3cb8ab23 --- /dev/null +++ b/implementations/sponge-8.0.0/src/main/java/de/bluecolored/bluemap/sponge8/EventForwarder.java @@ -0,0 +1,103 @@ +/* + * This file is part of BlueMap, licensed under the MIT License (MIT). + * + * Copyright (c) Blue (Lukas Rieger) + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package de.bluecolored.bluemap.sponge8; + +import de.bluecolored.bluemap.common.plugin.serverinterface.ServerEventListener; +import de.bluecolored.bluemap.common.plugin.text.Text; +import org.spongepowered.api.ResourceKey; +import org.spongepowered.api.Sponge; +import org.spongepowered.api.adventure.SpongeComponents; +import org.spongepowered.api.block.BlockSnapshot; +import org.spongepowered.api.data.Transaction; +import org.spongepowered.api.event.Listener; +import org.spongepowered.api.event.Order; +import org.spongepowered.api.event.block.ChangeBlockEvent; +import org.spongepowered.api.event.message.PlayerChatEvent; +import org.spongepowered.api.event.network.ServerSideConnectionEvent; +import org.spongepowered.api.event.world.chunk.ChunkEvent; +import org.spongepowered.api.world.server.ServerLocation; +import org.spongepowered.api.world.server.ServerWorld; + +import java.util.Optional; + +public class EventForwarder { + + private ServerEventListener listener; + + public EventForwarder(ServerEventListener 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 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 tr : evt.transactions()) { + if(!tr.isValid()) continue; + + Optional 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) + public void onPlayerJoin(ServerSideConnectionEvent.Join evt) { + listener.onPlayerJoin(evt.player().uniqueId()); + } + + @Listener(order = Order.POST) + public void onPlayerLeave(ServerSideConnectionEvent.Disconnect evt) { + listener.onPlayerJoin(evt.player().uniqueId()); + } + + @Listener(order = Order.POST) + public void onPlayerChat(PlayerChatEvent evt) { + listener.onChatMessage(Text.of(SpongeComponents.plainSerializer().serialize(evt.message()))); + } + +} diff --git a/implementations/sponge-8.0.0/src/main/java/de/bluecolored/bluemap/sponge8/Log4J2Logger.java b/implementations/sponge-8.0.0/src/main/java/de/bluecolored/bluemap/sponge8/Log4J2Logger.java new file mode 100644 index 00000000..c4cc35ed --- /dev/null +++ b/implementations/sponge-8.0.0/src/main/java/de/bluecolored/bluemap/sponge8/Log4J2Logger.java @@ -0,0 +1,68 @@ +/* + * This file is part of BlueMap, licensed under the MIT License (MIT). + * + * Copyright (c) Blue (Lukas Rieger) + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package de.bluecolored.bluemap.sponge8; + +import de.bluecolored.bluemap.core.logger.AbstractLogger; +import org.apache.logging.log4j.Logger; + +public class Log4J2Logger extends AbstractLogger { + + private Logger out; + + public Log4J2Logger(Logger out) { + this.out = out; + } + + @Override + public void logError(String message, Throwable throwable) { + out.error(message, throwable); + } + + @Override + public void logWarning(String message) { + out.warn(message); + } + + @Override + public void logInfo(String message) { + out.info(message); + } + + @Override + public void logDebug(String message) { + if (out.isDebugEnabled()) out.debug(message); + } + + @Override + public void noFloodDebug(String message) { + if (out.isDebugEnabled()) super.noFloodDebug(message); + } + + @Override + public void noFloodDebug(String key, String message) { + if (out.isDebugEnabled()) super.noFloodDebug(key, message); + } + +} diff --git a/implementations/sponge-8.0.0/src/main/java/de/bluecolored/bluemap/sponge8/SpongeCommandSource.java b/implementations/sponge-8.0.0/src/main/java/de/bluecolored/bluemap/sponge8/SpongeCommandSource.java new file mode 100644 index 00000000..d282e1e0 --- /dev/null +++ b/implementations/sponge-8.0.0/src/main/java/de/bluecolored/bluemap/sponge8/SpongeCommandSource.java @@ -0,0 +1,80 @@ +/* + * This file is part of BlueMap, licensed under the MIT License (MIT). + * + * Copyright (c) Blue (Lukas Rieger) + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package de.bluecolored.bluemap.sponge8; +import java.util.Optional; + +import net.kyori.adventure.audience.Audience; +import org.spongepowered.api.adventure.SpongeComponents; +import org.spongepowered.api.service.permission.Subject; +import org.spongepowered.api.world.Locatable; + +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; + +public class SpongeCommandSource implements CommandSource { + + private Plugin plugin; + private Audience audience; + private Subject subject; + + public SpongeCommandSource(Plugin plugin, Audience audience, Subject subject) { + this.plugin = plugin; + this.subject = subject; + this.audience = audience; + } + + @Override + public void sendMessage(Text text) { + audience.sendMessage(SpongeComponents.gsonSerializer().deserialize(text.toJSONString())); + } + + @Override + public boolean hasPermission(String permission) { + return subject.hasPermission(permission); + } + + @Override + public Optional getPosition() { + if (audience instanceof Locatable) { + return Optional.of(SpongePlugin.fromSpongePoweredVector(((Locatable) audience).location().position())); + } + + return Optional.empty(); + } + + @Override + public Optional getWorld() { + if (audience instanceof Locatable) { + return Optional.ofNullable(plugin.getWorld(((Locatable) audience).serverLocation().world().uniqueId())); + } + + return Optional.empty(); + } + +} diff --git a/implementations/sponge-8.0.0/src/main/java/de/bluecolored/bluemap/sponge8/SpongeCommands.java b/implementations/sponge-8.0.0/src/main/java/de/bluecolored/bluemap/sponge8/SpongeCommands.java new file mode 100644 index 00000000..7cd52bc9 --- /dev/null +++ b/implementations/sponge-8.0.0/src/main/java/de/bluecolored/bluemap/sponge8/SpongeCommands.java @@ -0,0 +1,161 @@ +/* + * This file is part of BlueMap, licensed under the MIT License (MIT). + * + * Copyright (c) Blue (Lukas Rieger) + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +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.exceptions.CommandSyntaxException; +import com.mojang.brigadier.suggestion.Suggestion; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.tree.CommandNode; + +import de.bluecolored.bluemap.common.plugin.Plugin; +import de.bluecolored.bluemap.common.plugin.commands.Commands; + +public class SpongeCommands { + + private CommandDispatcher dispatcher; + + public SpongeCommands(final Plugin plugin) { + this.dispatcher = new CommandDispatcher<>(); + + // register commands + // this assumes that every Subject will also be an Audience + new Commands<>(plugin, dispatcher, subject -> new SpongeCommandSource(plugin, (Audience) subject, subject)); + } + + public Collection getRootCommands(){ + Collection rootCommands = new ArrayList<>(); + + for (CommandNode node : this.dispatcher.getRoot().getChildren()) { + rootCommands.add(new SpongeCommandProxy(node.getName())); + } + + return rootCommands; + } + + public class SpongeCommandProxy implements Command.Raw { + + private String label; + + protected SpongeCommandProxy(String label) { + this.label = label; + } + + public String getLabel() { + return label; + } + + @Override + public CommandResult process(CommandCause cause, ArgumentReader.Mutable arguments) { + String command = label; + if (!arguments.input().isEmpty()) { + command += " " + arguments.input(); + } + + try { + return CommandResult.builder().result(dispatcher.execute(command, cause.subject())).build(); + } catch (CommandSyntaxException ex) { + cause.audience().sendMessage(Component.text(ex.getRawMessage().getString(), NamedTextColor.RED)); + + String context = ex.getContext(); + if (context != null) cause.audience().sendMessage(Component.text(context, NamedTextColor.GRAY)); + + return CommandResult.empty(); + } + } + + @Override + public List suggestions(CommandCause cause, ArgumentReader.Mutable arguments) { + String command = label; + if (!arguments.input().isEmpty()) { + command += " " + arguments.input(); + } + + List completions = new ArrayList<>(); + + try { + Suggestions suggestions = dispatcher.getCompletionSuggestions(dispatcher.parse(command, cause.subject())).get(100, TimeUnit.MILLISECONDS); + for (Suggestion suggestion : suggestions.getList()) { + String text = suggestion.getText(); + + if (text.indexOf(' ') == -1) { + completions.add(text); + } + } + } catch (InterruptedException ignore) { + Thread.currentThread().interrupt(); + } catch (ExecutionException | TimeoutException ignore) {} + + completions.sort(String::compareToIgnoreCase); + return completions; + } + + @Override + public boolean canExecute(CommandCause cause) { + return true; + } + + @Override + public Optional shortDescription(CommandCause cause) { + return Optional.empty(); + } + + @Override + public Optional extendedDescription(CommandCause cause) { + return Optional.empty(); + } + + @Override + public Component usage(CommandCause cause) { + CommandNode node = dispatcher.getRoot().getChild(label); + if (node == null) return Component.text("/" + label); + + List lines = new ArrayList<>(); + for (String usageString : dispatcher.getSmartUsage(node, cause.subject()).values()) { + lines.add(Component.text("/" + label + " ", NamedTextColor.WHITE).append(Component.text(usageString, NamedTextColor.GRAY))); + } + + return Component.join(Component.newline(), lines); + } + } + +} diff --git a/implementations/sponge-8.0.0/src/main/java/de/bluecolored/bluemap/sponge8/SpongePlayer.java b/implementations/sponge-8.0.0/src/main/java/de/bluecolored/bluemap/sponge8/SpongePlayer.java new file mode 100644 index 00000000..69e0dad9 --- /dev/null +++ b/implementations/sponge-8.0.0/src/main/java/de/bluecolored/bluemap/sponge8/SpongePlayer.java @@ -0,0 +1,143 @@ +/* + * This file is part of BlueMap, licensed under the MIT License (MIT). + * + * Copyright (c) Blue (Lukas Rieger) + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +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 org.spongepowered.api.Sponge; +import org.spongepowered.api.data.Keys; +import org.spongepowered.api.effect.potion.PotionEffect; +import org.spongepowered.api.effect.potion.PotionEffectTypes; +import org.spongepowered.api.entity.living.player.gamemode.GameMode; +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; + +public class SpongePlayer implements Player { + + private static final Map GAMEMODE_MAP = new HashMap<>(5); + static { + GAMEMODE_MAP.put(GameModes.ADVENTURE.get(), Gamemode.ADVENTURE); + GAMEMODE_MAP.put(GameModes.SURVIVAL.get(), Gamemode.SURVIVAL); + GAMEMODE_MAP.put(GameModes.CREATIVE.get(), Gamemode.CREATIVE); + GAMEMODE_MAP.put(GameModes.SPECTATOR.get(), Gamemode.SPECTATOR); + GAMEMODE_MAP.put(GameModes.NOT_SET.get(), Gamemode.SURVIVAL); + } + + private UUID uuid; + private Text name; + private UUID world; + private Vector3d position; + private boolean online; + private boolean sneaking; + private boolean invisible; + private Gamemode gamemode; + + public SpongePlayer(UUID playerUUID) { + this.uuid = playerUUID; + update(); + } + + @Override + public UUID getUuid() { + return this.uuid; + } + + @Override + public Text getName() { + return this.name; + } + + @Override + public UUID getWorld() { + return this.world; + } + + @Override + public Vector3d getPosition() { + return this.position; + } + + @Override + public boolean isOnline() { + return this.online; + } + + @Override + public boolean isSneaking() { + return this.sneaking; + } + + @Override + public boolean isInvisible() { + return this.invisible; + } + + @Override + public Gamemode getGamemode() { + return this.gamemode; + } + + /** + * API access, only call on server thread! + */ + public void update() { + ServerPlayer player = Sponge.server().player(uuid).orElse(null); + if (player == null) { + this.online = false; + return; + } + + this.gamemode = GAMEMODE_MAP.get(player.get(Keys.GAME_MODE).orElse(GameModes.NOT_SET.get())); + if (this.gamemode == null) this.gamemode = Gamemode.SURVIVAL; + + boolean invis = player.get(Keys.VANISH).orElse(false); + if (!invis && player.get(Keys.IS_INVISIBLE).orElse(false)) invis = true; + if (!invis) { + Optional> effects = player.get(Keys.POTION_EFFECTS); + if (effects.isPresent()) { + for (PotionEffect effect : effects.get()) { + if (effect.type().equals(PotionEffectTypes.INVISIBILITY.get()) && effect.duration() > 0) invis = true; + } + } + } + this.invisible = invis; + + this.name = Text.of(player.name()); + this.online = player.isOnline(); + this.position = SpongePlugin.fromSpongePoweredVector(player.position()); + this.sneaking = player.get(Keys.IS_SNEAKING).orElse(false); + this.world = player.world().uniqueId(); + } + +} diff --git a/implementations/sponge-8.0.0/src/main/java/de/bluecolored/bluemap/sponge8/SpongePlugin.java b/implementations/sponge-8.0.0/src/main/java/de/bluecolored/bluemap/sponge8/SpongePlugin.java new file mode 100644 index 00000000..3cf19bc7 --- /dev/null +++ b/implementations/sponge-8.0.0/src/main/java/de/bluecolored/bluemap/sponge8/SpongePlugin.java @@ -0,0 +1,323 @@ +/* + * This file is part of BlueMap, licensed under the MIT License (MIT). + * + * Copyright (c) Blue (Lukas Rieger) + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +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.Vector3d; +import com.flowpowered.math.vector.Vector3i; +import com.google.inject.Inject; +import org.spongepowered.api.Platform; +import org.spongepowered.api.ResourceKey; +import org.spongepowered.api.Server; +import org.spongepowered.api.Sponge; +import org.spongepowered.api.adventure.SpongeComponents; +import org.spongepowered.api.command.Command; +import org.spongepowered.api.config.ConfigDir; +import org.spongepowered.api.event.Listener; +import org.spongepowered.api.event.lifecycle.RefreshGameEvent; +import org.spongepowered.api.event.lifecycle.RegisterCommandEvent; +import org.spongepowered.api.event.lifecycle.StartedEngineEvent; +import org.spongepowered.api.event.lifecycle.StoppingEngineEvent; +import org.spongepowered.api.event.network.ServerSideConnectionEvent; +import org.spongepowered.api.scheduler.ScheduledTask; +import org.spongepowered.api.scheduler.Task; +import org.spongepowered.api.util.Ticks; +import org.spongepowered.api.util.Tristate; +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; + +@org.spongepowered.plugin.jvm.Plugin(Plugin.PLUGIN_ID) +public class SpongePlugin implements ServerInterface { + + private final PluginContainer pluginContainer; + @Inject + @ConfigDir(sharedRoot = false) + private Path configurationDir; + +// TODO Bstats needs updating +// @Inject +// @SuppressWarnings("unused") +// private MetricsLite2 metrics; + + private Plugin pluginInstance; + private SpongeCommands commands; + + private Map worldUUIDs = new ConcurrentHashMap<>(); + + private ExecutorService asyncExecutor; + private ExecutorService syncExecutor; + + private int playerUpdateIndex = 0; + private Map onlinePlayerMap; + private List onlinePlayerList; + + @Inject + public SpongePlugin(org.apache.logging.log4j.Logger logger, PluginContainer pluginContainer) { + Logger.global = new Log4J2Logger(logger); + this.pluginContainer = pluginContainer; + + this.onlinePlayerMap = new ConcurrentHashMap<>(); + this.onlinePlayerList = Collections.synchronizedList(new ArrayList<>()); + + final String versionFromSponge = Sponge.platform().container(Platform.Component.GAME).getMetadata().getVersion(); + MinecraftVersion version = MinecraftVersion.MC_1_16; + try { + version = MinecraftVersion.fromVersionString(versionFromSponge); + } catch (IllegalArgumentException e) { + Logger.global.logWarning("Failed to find a matching version for version-name '" + versionFromSponge + "'! Using latest known sponge-version: " + version.getVersionString()); + } + + this.pluginInstance = new Plugin(version, "sponge", this); + this.commands = new SpongeCommands(pluginInstance); + } + + @Listener + public void onRegisterCommands(final RegisterCommandEvent event) { + //register commands + for(SpongeCommandProxy command : commands.getRootCommands()) { + event.register(this.pluginContainer, command, command.getLabel()); + } + + } + + @Listener + public void onServerStart(StartedEngineEvent evt) { + asyncExecutor = evt.game().asyncScheduler().createExecutor(pluginContainer); + syncExecutor = evt.engine().scheduler().createExecutor(pluginContainer); + + //start updating players + Task task = Task.builder() + .interval(Ticks.of(1)) + .execute(this::updateSomePlayers) + .plugin(pluginContainer) + .build(); + evt.engine().scheduler().submit(task); + + asyncExecutor.execute(() -> { + try { + Logger.global.logInfo("Loading..."); + pluginInstance.load(); + if (pluginInstance.isLoaded()) Logger.global.logInfo("Loaded!"); + } catch (IOException | ParseResourceException | RuntimeException e) { + Logger.global.logError("Failed to load!", e); + pluginInstance.unload(); + } + }); + } + + @Listener + public void onServerStop(StoppingEngineEvent evt) { + Logger.global.logInfo("Stopping..."); + evt.engine().scheduler().tasksByPlugin(pluginContainer).forEach(ScheduledTask::cancel); + pluginInstance.unload(); + Logger.global.logInfo("Saved and stopped!"); + } + + @Listener + public void onServerReload(RefreshGameEvent evt) { + asyncExecutor.execute(() -> { + try { + Logger.global.logInfo("Reloading..."); + pluginInstance.reload(); + Logger.global.logInfo("Reloaded!"); + } catch (IOException | ParseResourceException | RuntimeException e) { + Logger.global.logError("Failed to load!", e); + pluginInstance.unload(); + } + }); + } + + @Listener + public void onPlayerJoin(ServerSideConnectionEvent.Join evt) { + SpongePlayer player = new SpongePlayer(evt.player().uniqueId()); + onlinePlayerMap.put(evt.player().uniqueId(), player); + onlinePlayerList.add(player); + } + + @Listener + public void onPlayerLeave(ServerSideConnectionEvent.Disconnect evt) { + UUID playerUUID = evt.player().uniqueId(); + onlinePlayerMap.remove(playerUUID); + synchronized (onlinePlayerList) { + onlinePlayerList.removeIf(p -> p.getUuid().equals(playerUUID)); + } + } + + @Override + public void registerListener(ServerEventListener listener) { + Sponge.eventManager().registerListeners(this.pluginContainer, new EventForwarder(listener)); + } + + @Override + public void unregisterAllListeners() { + Sponge.eventManager().unregisterPluginListeners(this.pluginContainer); + Sponge.eventManager().registerListeners(this.pluginContainer, this); + } + + @Override + public UUID getUUIDForWorld(File worldFolder) throws IOException { + // this logic derives the the world key from the folder structure + final Pattern customDimension = Pattern.compile(".+/dimensions/([a-z0-9_.-]+)/([a-z0-9._-]+)$".replace("/", File.separator)); + final Matcher matcher = customDimension.matcher(worldFolder.toString()); + final ResourceKey key; + if (matcher.matches()) { + key = ResourceKey.of(matcher.group(1), matcher.group(2)); + } else if ("DIM-1".equals(worldFolder.getName())) { + key = ResourceKey.minecraft("the_nether"); + } 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 + public String getWorldName(UUID worldUUID) { + return getServerWorld(worldUUID) + .map(serverWorld -> serverWorld + .properties() + .displayName() + .map(SpongeComponents.plainSerializer()::serialize) + .orElse(serverWorld.key().asString())) + .orElse(null); + } + + private Optional getServerWorld(UUID worldUUID) { + return Sponge.server().worldManager().worldKey(worldUUID).flatMap(k -> Sponge.server().worldManager().world(k)); + } + + @Override + public File getConfigFolder() { + return configurationDir.toFile(); + } + + @Override + public Collection getOnlinePlayers() { + return onlinePlayerMap.values(); + } + + @Override + public Optional getPlayer(UUID uuid) { + return Optional.ofNullable(onlinePlayerMap.get(uuid)); + } + + @Override + public boolean isMetricsEnabled(boolean configValue) { + if (pluginContainer != null) { + Tristate metricsEnabled = Sponge.metricsConfigManager().collectionState(pluginContainer); + if (metricsEnabled != Tristate.UNDEFINED) { + return metricsEnabled == Tristate.TRUE ? true : false; + } + } + + return Sponge.metricsConfigManager().globalCollectionState().asBoolean(); + } + + @Override + public boolean persistWorldChanges(UUID worldUUID) throws IOException, IllegalArgumentException { + try { + return syncExecutor.submit(() -> { + ServerWorld world = getServerWorld(worldUUID).orElse(null); + if (world == null) throw new IllegalArgumentException("There is no world with this uuid: " + worldUUID); + world.save(); + + return true; + }).get(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new IOException(e); + } catch (ExecutionException e) { + Throwable t = e.getCause(); + if (t instanceof IOException) throw (IOException) t; + if (t instanceof IllegalArgumentException) throw (IllegalArgumentException) t; + throw new IOException(t); + } + } + + /** + * Only update some of the online players each tick to minimize performance impact on the server-thread. + * Only call this method on the server-thread. + */ + private void updateSomePlayers() { + int onlinePlayerCount = onlinePlayerList.size(); + if (onlinePlayerCount == 0) return; + + int playersToBeUpdated = onlinePlayerCount / 20; //with 20 tps, each player is updated once a second + if (playersToBeUpdated == 0) playersToBeUpdated = 1; + + for (int i = 0; i < playersToBeUpdated; i++) { + playerUpdateIndex++; + if (playerUpdateIndex >= 20 && playerUpdateIndex >= onlinePlayerCount) playerUpdateIndex = 0; + + if (playerUpdateIndex < onlinePlayerCount) { + onlinePlayerList.get(playerUpdateIndex).update(); + } + } + } + + public static Vector3d fromSpongePoweredVector(org.spongepowered.math.vector.Vector3d vec) { + return new Vector3d(vec.getX(), vec.getY(), vec.getZ()); + } + + public static Vector3i fromSpongePoweredVector(org.spongepowered.math.vector.Vector3i vec) { + return new Vector3i(vec.getX(), vec.getY(), vec.getZ()); + } + + public static Vector2i fromSpongePoweredVector(org.spongepowered.math.vector.Vector2i vec) { + return new Vector2i(vec.getX(), vec.getY()); + } + +} diff --git a/implementations/sponge-8.0.0/src/main/resources/META-INF/plugins.json b/implementations/sponge-8.0.0/src/main/resources/META-INF/plugins.json new file mode 100644 index 00000000..599c8356 --- /dev/null +++ b/implementations/sponge-8.0.0/src/main/resources/META-INF/plugins.json @@ -0,0 +1,31 @@ +{ + "plugins": [ + { + "loader": "java_plain", + "id": "bluemap", + "name": "BlueMap", + "version": "${version}", + "main-class": "de.bluecolored.bluemap.sponge8.SpongePlugin", + "description": "A 3d-map of your Minecraft worlds view-able in your browser using three.js (WebGL)", + "links": { + "homepage": "https://bluecolo.red/bluemap", + "source": "https://github.com/BlueMap-Minecraft/BlueMap", + "issues": "https://github.com/BlueMap-Minecraft/BlueMap/issues" + }, + "contributors": [ + { + "name": "Blue (TBlueF, Lukas Rieger)", + "description": "Lead Developer" + } + ], + "dependencies": [ + { + "id": "spongeapi", + "version": "8.0.0", + "load-order": "AFTER", + "optional": false + } + ] + } + ] +} diff --git a/implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/core-defaults.conf b/implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/core-defaults.conf new file mode 100644 index 00000000..e51cf511 --- /dev/null +++ b/implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/core-defaults.conf @@ -0,0 +1,4 @@ +accept-download: false +renderThreadCount: -2 +metrics: false +data: "bluemap" \ No newline at end of file diff --git a/implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/core.conf b/implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/core.conf new file mode 100644 index 00000000..0b85eb35 --- /dev/null +++ b/implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/core.conf @@ -0,0 +1,24 @@ +## ## +## BlueMap ## +## Core-Config ## +## ## + +# By changing the setting (accept-download) below to TRUE you are indicating that you have accepted mojang's EULA (https://account.mojang.com/documents/minecraft_eula), +# you confirm that you own a license to Minecraft (Java Edition) +# and you agree that BlueMap will download and use a minecraft-client file (depending on the minecraft-version) from mojangs servers (https://launcher.mojang.com/) for you. +# This file contains resources that belong to mojang and you must not redistribute it or do anything else that is not compliant with mojang's EULA. +# BlueMap uses resources in this file to generate the 3D-Models used for the map and texture them. (BlueMap will not work without those resources.) +# %datetime-iso% +accept-download: false + +# This changes the amount of threads that BlueMap will use to render the maps. +# A higher value can improve render-speed but could impact performance on the host machine. +# This should be always below or equal to the number of available processor-cores. +# Zero or a negative value means the amount of of available processor-cores subtracted by the value. +# (So a value of -2 with 6 cores results in 4 render-processes) +# Default is -2 +renderThreadCount: -2 + +# The folder where bluemap saves data-files it needs during runtime or to save e.g. the render-progress to resume it later. +# Default is "bluemap" +data: "bluemap" \ No newline at end of file diff --git a/implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/plugin-defaults.conf b/implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/plugin-defaults.conf new file mode 100644 index 00000000..1fbe5b17 --- /dev/null +++ b/implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/plugin-defaults.conf @@ -0,0 +1,5 @@ +liveUpdates: true +skinDownload: false +hiddenGameModes: [] +hideInvisible: true +hideSneaking: false \ No newline at end of file diff --git a/implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/plugin.conf b/implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/plugin.conf new file mode 100644 index 00000000..a3d3a014 --- /dev/null +++ b/implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/plugin.conf @@ -0,0 +1,27 @@ +## ## +## BlueMap ## +## Plugin-Config ## +## ## + +# If the server should send live-updates and player-positions. +# This only works if the integrated webserver is enabled. +# Default is true +liveUpdates: true + +# Download the skin from mojang-serves when a player joins your server, so it can be used for the player-markers. +# Default is false +skinDownload: false + +# A list of gamemodes that will prevent a player from appearing on the map. +# Possible values are: survival, creative, spectator, adventure +hiddenGameModes: [ + "spectator" +] + +# If this is true, players that have an invisibility (potion-)effect will be hidden on the map. +# Default is true +hideInvisible: true + +# If this is true, players that are sneaking will be hidden on the map. +# Default is false +hideSneaking: false \ No newline at end of file diff --git a/implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/render-defaults.conf b/implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/render-defaults.conf new file mode 100644 index 00000000..2f276c92 --- /dev/null +++ b/implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/render-defaults.conf @@ -0,0 +1,3 @@ +webroot: "bluemap/web" +useCookies: true +maps: [] diff --git a/implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/render.conf b/implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/render.conf new file mode 100644 index 00000000..1efd4978 --- /dev/null +++ b/implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/render.conf @@ -0,0 +1,126 @@ +## ## +## BlueMap ## +## Render-Config ## +## ## + +# The folder (webroot) where the map-data and web-application files will be saved. +# Default is "bluemap/web" +webroot: "bluemap/web" + +# If the web-application should use cookies to save the configurations of a user. +# Default is true +useCookies: true + +# This is an array with multiple configured maps. +# You can define multiple maps, for different worlds with different render-settings here +maps: [ + + { + # The id of this map + # Should only contain word-charactes: [a-zA-Z0-9_] + # Changing this value breaks your existing renders. + id: "world" + + # The name of this map + # This defines the display name of this map, you can change this at any time. + # Default is the id of this map + name: "World" + + # The path to the save-folder of the world to render. + world: "world" + + # The position on the world where the map will be centered if you open it. + # You can change this at any time. + # This defaults to the world-spawn if you don't set it. + #startPos: [500, -820] + + # The color of thy sky as a hex-color + # You can change this at any time. + # Default is "#7dabff" + skyColor: "#7dabff" + + # Defines the ambient light-strength that every block is recieving, regardless of the sunlight/blocklight. + # 0 is no ambient light, 1 is fully lighted. + # You can change this at any time. + # Default is 0 + ambientLight: 0 + + # If this is false, BlueMap tries to omit all blocks that are not visible from above-ground. + # More specific: Block-Faces that have a sunlight/skylight value of 0 are removed. + # This improves the performance of the map on slower devices by a lot, but might cause some blocks to disappear that should normally be visible. + # Changing this value requires a re-render of the map. + # Default is false + renderCaves: false + + # With the below values you can limit the map-render. + # This can be used to ignore the nethers ceiling or render only a certain part of a world. + # Changing this values might require a re-render of the map, already rendered tiles outside the limits will not be deleted. + # Default is no min or max value (= infinite bounds) + #minX: -4000 + #maxX: 4000 + #minZ: -4000 + #maxZ: 4000 + #minY: 50 + #maxY: 126 + + # Using this, BlueMap pretends that every Block out of the defined render-bounds is AIR, + # this means you can see the blocks where the world is cut (instead of having a see-through/xray view). + # This has only an effect if you set some render-bounds above. + # Changing this value requires a re-render of the map. + # Default is true + renderEdges: true + + # With this set to true, the generated files for this world are compressed using gzip to save A LOT of space. + # Files will be only 5% as big with compression! + # Note: If you are using NGINX or Apache to host your map, you can configure them to serve the compressed files directly. + # This is much better than disabling the compression. + # Changing this value requires a re-render of the map. + # Default is true + useCompression: true + + # Normally BlueMap detects if a chunk has not yet generated it's light-data and omits rendering those chunks. + # If this is set to true BlueMap will render Chunks even if there is no light-data! + # This can be usefull for example if some mod prevents light-data from being saved correctly. + # However, this also has a few drawbacks: + # - For those chunks, every block will always be fully lit + # - Night-mode might not work correctly + # - Caves will always be rendered (ignoring the 'renderCaves' setting) + # Default is false + ignoreMissingLightData: false + } + + # Here another example for the End-Map + # Things we don't want to change from default we can just omit + { + id: "end" + name: "End" + world: "world/DIM1" + + # We dont want a blue sky in the end + skyColor: "#080010" + + # In the end is no sky-light, so we need to enable this or we won't see anything. + renderCaves: true + + # Same here, we don't want a dark map. But not completely lighted, so we see the effect of e.g torches. + ambientLight: 0.6 + } + + # Here another example for the Nether-Map + { + id: "nether" + name: "Nether" + world: "world/DIM-1" + + skyColor: "#290000" + + renderCaves: true + ambientLight: 0.6 + + # We slice the whole world at y:90 so every block above 90 will be air. + # This way we don't render the nethers ceiling. + maxY: 90 + renderEdges: true + } + +] diff --git a/implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/webserver-defaults.conf b/implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/webserver-defaults.conf new file mode 100644 index 00000000..55e8c255 --- /dev/null +++ b/implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/webserver-defaults.conf @@ -0,0 +1,4 @@ +enabled: true +webroot: "bluemap/web" +port: 8100 +maxConnectionCount: 100 \ No newline at end of file diff --git a/implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/webserver.conf b/implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/webserver.conf new file mode 100644 index 00000000..6af072df --- /dev/null +++ b/implementations/sponge-8.0.0/src/main/resources/de/bluecolored/bluemap/webserver.conf @@ -0,0 +1,29 @@ +## ## +## BlueMap ## +## Webserver-Config ## +## ## + +# With this setting you can disable the integrated web-server. +# This is usefull if you want to only render the map-data for later use, or if you setup your own webserver. +# Default is enabled +enabled: true + +# The webroot that the server will host to the web. +# Usually this should be set to the same directory like in the render.conf! +# Default is "bluemap/web" +webroot: "bluemap/web" + +# The IP-Adress that the webserver binds to. +# Use "0.0.0.0" to bind to all available local adresses. +# If you only want to access it locally use "localhost". +# Default is "0.0.0.0" +#ip: "localhost" +#ip: "123.45.6.78" + +# The port that the webserver listenes to. +# Default is 8100 +port: 8100 + +# Max number of simultaneous connections that the webserver allows +# Default is 100 +maxConnectionCount: 100 \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 5cbf959b..dd117d46 100644 --- a/settings.gradle +++ b/settings.gradle @@ -18,6 +18,7 @@ include ':BlueMapCommon' include ':cli' include ':sponge-7.2.0' +include ':sponge-8.0.0' include ':spigot' include ':forge-1.16.2' @@ -35,6 +36,7 @@ project(':BlueMapCommon').projectDir = "$rootDir/BlueMapCommon" as File project(':cli').projectDir = "$rootDir/implementations/cli" as File project(':sponge-7.2.0').projectDir = "$rootDir/implementations/sponge-7.2.0" as File +project(':sponge-8.0.0').projectDir = "$rootDir/implementations/sponge-8.0.0" as File project(':spigot').projectDir = "$rootDir/implementations/spigot" as File project(':forge-1.16.2').projectDir = "$rootDir/implementations/forge-1.16.2" as File