From c6e7df919a6d54e3f21ecbfd8fa7517b7ca274a1 Mon Sep 17 00:00:00 2001
From: Matt <4009945+MattBDev@users.noreply.github.com>
Date: Fri, 28 Jan 2022 00:04:45 -0500
Subject: [PATCH] Let's bring back Sponge.
---
Sponge/build.gradle.kts | 81 ++++++
.../plotsquared/sponge/SpongePlatform.java | 174 +++++++++++++
.../sponge/inject/SpongeModule.java | 106 ++++++++
.../sponge/player/SpongeOfflinePlayer.java | 37 +++
.../sponge/player/SpongePlayer.java | 243 ++++++++++++++++++
.../sponge/player/SpongePlayerManager.java | 86 +++++++
.../sponge/util/SpongeEconHandler.java | 71 +++++
.../plotsquared/sponge/util/SpongeUtil.java | 7 +
.../plotsquared/sponge/util/SpongeWorld.java | 25 ++
.../sponge/util/task/SpongeTaskManager.java | 69 +++++
.../sponge/util/task/SpongeTimeConverter.java | 20 ++
build.gradle.kts | 1 +
gradle/libs.versions.toml | 3 +-
settings.gradle.kts | 3 +-
14 files changed, 924 insertions(+), 2 deletions(-)
create mode 100644 Sponge/build.gradle.kts
create mode 100644 Sponge/src/main/java/com/plotsquared/sponge/SpongePlatform.java
create mode 100644 Sponge/src/main/java/com/plotsquared/sponge/inject/SpongeModule.java
create mode 100644 Sponge/src/main/java/com/plotsquared/sponge/player/SpongeOfflinePlayer.java
create mode 100644 Sponge/src/main/java/com/plotsquared/sponge/player/SpongePlayer.java
create mode 100644 Sponge/src/main/java/com/plotsquared/sponge/player/SpongePlayerManager.java
create mode 100644 Sponge/src/main/java/com/plotsquared/sponge/util/SpongeEconHandler.java
create mode 100644 Sponge/src/main/java/com/plotsquared/sponge/util/SpongeUtil.java
create mode 100644 Sponge/src/main/java/com/plotsquared/sponge/util/SpongeWorld.java
create mode 100644 Sponge/src/main/java/com/plotsquared/sponge/util/task/SpongeTaskManager.java
create mode 100644 Sponge/src/main/java/com/plotsquared/sponge/util/task/SpongeTimeConverter.java
diff --git a/Sponge/build.gradle.kts b/Sponge/build.gradle.kts
new file mode 100644
index 000000000..84128fd76
--- /dev/null
+++ b/Sponge/build.gradle.kts
@@ -0,0 +1,81 @@
+import org.spongepowered.gradle.plugin.config.PluginLoaders
+import org.spongepowered.plugin.metadata.model.PluginDependency
+
+plugins {
+ id("org.spongepowered.gradle.plugin") version "2.0.0"
+}
+
+dependencies {
+ api(projects.plotSquaredCore)
+
+ compileOnly(libs.worldeditSponge)
+}
+
+sponge {
+ apiVersion("8.0.0")
+ license("All Rights Reserved")
+ loader {
+ name(PluginLoaders.JAVA_PLAIN)
+ version("1.0")
+ }
+ plugin("sponge") {
+ displayName("PlotSquared")
+ entrypoint("com.plotsquared.sponge.SpongePlatform")
+ description("Easy, yet powerful Plot World generation and management.")
+ links {
+ // homepage("https://spongepowered.org")
+ // source("https://spongepowered.org/source")
+ // issues("https://spongepowered.org/issues")
+ }
+ contributor("Citymonstret") {
+ description("Author")
+ }
+ contributor("Empire92") {
+ description("Author")
+ }
+ contributor("MattBDev") {
+ description("Author")
+ }
+ contributor("dordsor21") {
+ description("Author")
+ }
+ contributor("NotMyFault") {
+ description("Author")
+ }
+ contributor("SirYwell") {
+ description("Author")
+ }
+ dependency("spongeapi") {
+ loadOrder(PluginDependency.LoadOrder.AFTER)
+ optional(false)
+ }
+// dependency("${DEPEDENCY}") {
+// loadOrder(PluginDependency.LoadOrder.AFTER)
+// optional(false)
+// }
+ }
+}
+
+val javaTarget = 16
+java {
+ sourceCompatibility = JavaVersion.toVersion(javaTarget)
+ targetCompatibility = JavaVersion.toVersion(javaTarget)
+ if (JavaVersion.current() < JavaVersion.toVersion(javaTarget)) {
+ toolchain.languageVersion.set(JavaLanguageVersion.of(javaTarget))
+ }
+}
+
+tasks.withType(JavaCompile::class).configureEach {
+ options.apply {
+ encoding = "utf-8" // Consistent source file encoding
+ if (JavaVersion.current().isJava10Compatible) {
+ release.set(javaTarget)
+ }
+ }
+}
+
+// Make sure all tasks which produce archives (jar, sources jar, javadoc jar, etc) produce more consistent output
+tasks.withType(AbstractArchiveTask::class).configureEach {
+ isReproducibleFileOrder = true
+ isPreserveFileTimestamps = false
+}
diff --git a/Sponge/src/main/java/com/plotsquared/sponge/SpongePlatform.java b/Sponge/src/main/java/com/plotsquared/sponge/SpongePlatform.java
new file mode 100644
index 000000000..bda5038e2
--- /dev/null
+++ b/Sponge/src/main/java/com/plotsquared/sponge/SpongePlatform.java
@@ -0,0 +1,174 @@
+package com.plotsquared.sponge;
+
+import com.google.inject.Guice;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Stage;
+import com.plotsquared.core.PlotPlatform;
+import com.plotsquared.core.PlotSquared;
+import com.plotsquared.core.configuration.Settings;
+import com.plotsquared.core.inject.modules.PlotSquaredModule;
+import com.plotsquared.core.plot.world.PlotAreaManager;
+import com.plotsquared.core.util.task.TaskManager;
+import com.plotsquared.core.util.task.TaskTime;
+import com.plotsquared.sponge.inject.SpongeModule;
+import com.plotsquared.sponge.util.task.SpongeTaskManager;
+import com.plotsquared.sponge.util.task.SpongeTimeConverter;
+import net.kyori.adventure.identity.Identity;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.LinearComponents;
+import net.kyori.adventure.text.format.NamedTextColor;
+import net.kyori.adventure.text.format.Style;
+import net.kyori.adventure.text.format.TextDecoration;
+import org.apache.logging.log4j.Logger;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.spongepowered.api.Game;
+import org.spongepowered.api.Server;
+import org.spongepowered.api.Sponge;
+import org.spongepowered.api.command.Command;
+import org.spongepowered.api.command.CommandResult;
+import org.spongepowered.api.command.parameter.Parameter;
+import org.spongepowered.api.config.ConfigDir;
+import org.spongepowered.api.entity.living.player.Player;
+import org.spongepowered.api.entity.living.player.server.ServerPlayer;
+import org.spongepowered.api.event.Listener;
+import org.spongepowered.api.event.lifecycle.ConstructPluginEvent;
+import org.spongepowered.api.event.lifecycle.RegisterCommandEvent;
+import org.spongepowered.api.event.lifecycle.StartingEngineEvent;
+import org.spongepowered.api.event.lifecycle.StoppingEngineEvent;
+import org.spongepowered.plugin.PluginContainer;
+import org.spongepowered.plugin.builtin.jvm.Plugin;
+
+import java.io.File;
+import java.nio.file.Path;
+
+/**
+ * The main class of your Sponge plugin.
+ *
+ *
All methods are optional -- some common event registrations are included as a jumping-off point.
+ */
+@Plugin("sponge")
+public class SpongePlatform implements PlotPlatform {
+
+ public final PluginContainer container;
+ private final Logger logger;
+ private final Game game;
+
+
+ @Inject
+ private PlotAreaManager plotAreaManager;
+
+ @Inject
+ @ConfigDir(sharedRoot = false)
+ private Path configDir;
+
+ private int[] version;
+ private Injector injector;
+
+ @Inject
+ SpongePlatform(final PluginContainer container, final Logger logger, final Game game) {
+ this.container = container;
+ this.logger = logger;
+ this.game = game;
+ }
+
+ @Listener
+ public void onConstructPlugin(final ConstructPluginEvent event) {
+ // Perform any one-time setup
+ this.logger.info("Constructing sponge");
+ final TaskTime.TimeConverter timeConverter = new SpongeTimeConverter();
+ TaskManager.setPlatformImplementation(new SpongeTaskManager(this, timeConverter));
+
+ final PlotSquared plotSquared = new PlotSquared(this, "Sponge");
+
+ if (Settings.FAWE_Components.FAWE_HOOK) {
+ this.logger.info("FAWE Hooks do not work on Sponge. 😞");
+ }
+
+ // We create the injector after PlotSquared has been initialized, so that we have access
+ // to generated instances and settings
+ this.injector = Guice
+ .createInjector(
+ Stage.PRODUCTION,
+ new PermissionModule(),
+ new WorldManagerModule(),
+ new PlotSquaredModule(),
+ new SpongeModule(this),
+ new BackupModule()
+ );
+
+ }
+
+ @Listener
+ public void onServerStarting(final StartingEngineEvent event) {
+ // Any setup per-game instance. This can run multiple times when
+ // using the integrated (single-player) server.
+ }
+
+ @Listener
+ public void onServerStopping(final StoppingEngineEvent event) {
+ // Any tear down per-game instance. This can run multiple times when
+ // using the integrated (single-player) server.
+ }
+
+ @Listener
+ public void onRegisterCommands(final RegisterCommandEvent event) {
+ // Register a simple command
+ // When possible, all commands should be registered within a command register event
+ final Parameter.Value nameParam = Parameter.string().key("name").build();
+ event.register(this.container, Command.builder()
+ .addParameter(nameParam)
+ .permission("sponge.command.greet")
+ .executor(ctx -> {
+ final String name = ctx.requireOne(nameParam);
+ ctx.sendMessage(Identity.nil(), LinearComponents.linear(
+ NamedTextColor.AQUA,
+ Component.text("Hello "),
+ Component.text(name, Style.style(TextDecoration.BOLD)),
+ Component.text("!")
+ ));
+
+ return CommandResult.success();
+ })
+ .build(), "greet", "wave");
+ }
+
+ @Override
+ public int[] serverVersion() {
+ if (this.version == null) {
+ try {
+ this.version = new int[3];
+ String[] split = Sponge.platform().minecraftVersion().name().split("\\.");
+ this.version[0] = Integer.parseInt(split[0]);
+ this.version[1] = Integer.parseInt(split[1]);
+ if (split.length == 3) {
+ this.version[2] = Integer.parseInt(split[2]);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ return new int[]{1, 16, 5};
+ }
+ }
+ return this.version;
+ }
+
+ @Override
+ public @NonNull String serverImplementation() {
+ return "Sponge"; //TODO Possibly revaluate the this method name
+ }
+
+ @Override
+ public @NonNull File getDirectory() {
+ return configDir.toFile();
+ }
+
+ @Override
+ public @NonNull File worldContainer() {
+ return game.gameDirectory().toFile(); //TODO This may be incorrect. Behavior needs verification.
+ }
+
+ public Logger getLogger() {
+ return logger;
+ }
+
+}
diff --git a/Sponge/src/main/java/com/plotsquared/sponge/inject/SpongeModule.java b/Sponge/src/main/java/com/plotsquared/sponge/inject/SpongeModule.java
new file mode 100644
index 000000000..2c6386f39
--- /dev/null
+++ b/Sponge/src/main/java/com/plotsquared/sponge/inject/SpongeModule.java
@@ -0,0 +1,106 @@
+package com.plotsquared.sponge.inject;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Provides;
+import com.google.inject.Singleton;
+import com.google.inject.assistedinject.FactoryModuleBuilder;
+import com.plotsquared.core.PlotPlatform;
+import com.plotsquared.core.PlotSquared;
+import com.plotsquared.core.configuration.Settings;
+import com.plotsquared.core.generator.HybridGen;
+import com.plotsquared.core.generator.IndependentPlotGenerator;
+import com.plotsquared.core.inject.annotations.ConsoleActor;
+import com.plotsquared.core.inject.annotations.DefaultGenerator;
+import com.plotsquared.core.inject.factory.ChunkCoordinatorBuilderFactory;
+import com.plotsquared.core.inject.factory.ChunkCoordinatorFactory;
+import com.plotsquared.core.inject.factory.HybridPlotWorldFactory;
+import com.plotsquared.core.inject.factory.ProgressSubscriberFactory;
+import com.plotsquared.core.plot.world.DefaultPlotAreaManager;
+import com.plotsquared.core.plot.world.PlotAreaManager;
+import com.plotsquared.core.plot.world.SinglePlotAreaManager;
+import com.plotsquared.core.queue.ChunkCoordinator;
+import com.plotsquared.core.queue.GlobalBlockQueue;
+import com.plotsquared.core.queue.QueueProvider;
+import com.plotsquared.core.queue.subscriber.DefaultProgressSubscriber;
+import com.plotsquared.core.queue.subscriber.ProgressSubscriber;
+import com.plotsquared.core.util.ChunkManager;
+import com.plotsquared.core.util.EconHandler;
+import com.plotsquared.core.util.InventoryUtil;
+import com.plotsquared.core.util.PlayerManager;
+import com.plotsquared.core.util.RegionManager;
+import com.plotsquared.core.util.SchematicHandler;
+import com.plotsquared.core.util.SetupUtils;
+import com.plotsquared.core.util.WorldUtil;
+import com.plotsquared.sponge.SpongePlatform;
+import com.plotsquared.sponge.player.SpongePlayerManager;
+import com.plotsquared.sponge.util.SpongeEconHandler;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.spongepowered.api.Sponge;
+import org.spongepowered.api.service.economy.EconomyService;
+
+public class SpongeModule extends AbstractModule {
+
+ private final SpongePlatform spongePlatform;
+
+ public SpongeModule(SpongePlatform spongePlatform) {
+ this.spongePlatform = spongePlatform;
+ }
+
+ @Override
+ protected void configure() {
+ bind(PlayerManager.class).to(SpongePlayerManager.class);
+ bind(PlotPlatform.class).toInstance(spongePlatform);
+ bind(SpongePlatform.class).toInstance(spongePlatform);
+ bind(IndependentPlotGenerator.class).annotatedWith(DefaultGenerator.class).to(HybridGen.class);
+ // Console actor
+ @NonNull ConsoleCommandSender console = Sponge.server().getServer().getConsoleSender();
+ WorldEditPlugin wePlugin = ((WorldEditPlugin) Bukkit.getPluginManager().getPlugin("WorldEdit"));
+ bind(Actor.class).annotatedWith(ConsoleActor.class).toInstance(wePlugin.wrapCommandSender(console));
+ bind(InventoryUtil.class).to(BukkitInventoryUtil.class);
+ bind(SetupUtils.class).to(BukkitSetupUtils.class);
+ bind(WorldUtil.class).to(BukkitUtil.class);
+ install(new FactoryModuleBuilder()
+ .implement(ProgressSubscriber.class, DefaultProgressSubscriber.class)
+ .build(ProgressSubscriberFactory.class));
+ bind(ChunkManager.class).to(BukkitChunkManager.class);
+ if (PlotSquared.platform().isFaweHooking()) {
+ bind(SchematicHandler.class).to(FaweSchematicHandler.class);
+ bind(RegionManager.class).to(FaweRegionManager.class);
+ } else {
+ bind(SchematicHandler.class).to(BukkitSchematicHandler.class);
+ bind(RegionManager.class).to(BukkitRegionManager.class);
+ }
+ bind(GlobalBlockQueue.class).toInstance(new GlobalBlockQueue(QueueProvider.of(BukkitQueueCoordinator.class)));
+ if (Settings.Enabled_Components.WORLDS) {
+ bind(PlotAreaManager.class).to(SinglePlotAreaManager.class);
+ try {
+ bind(SingleWorldListener.class).toInstance(new SingleWorldListener());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ } else {
+ bind(PlotAreaManager.class).to(DefaultPlotAreaManager.class);
+ }
+ install(new FactoryModuleBuilder().build(HybridPlotWorldFactory.class));
+ install(new FactoryModuleBuilder()
+ .implement(ChunkCoordinator.class, BukkitChunkCoordinator.class)
+ .build(ChunkCoordinatorFactory.class));
+ install(new FactoryModuleBuilder().build(ChunkCoordinatorBuilderFactory.class));
+ }
+
+ @Provides
+ @Singleton
+ @NonNull EconHandler provideEconHandler() {
+ if (!Settings.Enabled_Components.ECONOMY) {
+ return EconHandler.nullEconHandler();
+ }
+ SpongeEconHandler economyService = new SpongeEconHandler();
+
+ if (!economyService.isSupported()) {
+ spongePlatform.getLogger().warn("Economy is enabled but no plugin is providing an economy service.");
+ }
+
+ return economyService;
+ }
+
+}
diff --git a/Sponge/src/main/java/com/plotsquared/sponge/player/SpongeOfflinePlayer.java b/Sponge/src/main/java/com/plotsquared/sponge/player/SpongeOfflinePlayer.java
new file mode 100644
index 000000000..b27813ac8
--- /dev/null
+++ b/Sponge/src/main/java/com/plotsquared/sponge/player/SpongeOfflinePlayer.java
@@ -0,0 +1,37 @@
+package com.plotsquared.sponge.player;
+
+import com.plotsquared.core.player.OfflinePlotPlayer;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+import java.util.UUID;
+
+//TODO Implement
+public class SpongeOfflinePlayer implements @Nullable
+ OfflinePlotPlayer {
+
+ @Override
+ public boolean hasPermission(@Nullable final String world, @NonNull final String permission) {
+ return false;
+ }
+
+ @Override
+ public boolean hasKeyedPermission(@Nullable final String world, @NonNull final String permission, @NonNull final String key) {
+ return false;
+ }
+
+ @Override
+ public UUID getUUID() {
+ return null;
+ }
+
+ @Override
+ public long getLastPlayed() {
+ return 0;
+ }
+
+ @Override
+ public String getName() {
+ return null;
+ }
+}
diff --git a/Sponge/src/main/java/com/plotsquared/sponge/player/SpongePlayer.java b/Sponge/src/main/java/com/plotsquared/sponge/player/SpongePlayer.java
new file mode 100644
index 000000000..53d2f7904
--- /dev/null
+++ b/Sponge/src/main/java/com/plotsquared/sponge/player/SpongePlayer.java
@@ -0,0 +1,243 @@
+/*
+ * _____ _ _ _____ _
+ * | __ \| | | | / ____| | |
+ * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
+ * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
+ * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
+ * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
+ * | |
+ * |_|
+ * PlotSquared plot management system for Minecraft
+ * Copyright (C) 2014 - 2022 IntellectualSites
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package com.plotsquared.sponge.player;
+
+import com.plotsquared.core.events.TeleportCause;
+import com.plotsquared.core.location.Location;
+import com.plotsquared.core.permissions.PermissionHandler;
+import com.plotsquared.core.player.ConsolePlayer;
+import com.plotsquared.core.player.PlotPlayer;
+import com.plotsquared.core.plot.PlotWeather;
+import com.plotsquared.core.plot.world.PlotAreaManager;
+import com.plotsquared.core.util.EventDispatcher;
+import com.plotsquared.sponge.util.SpongeUtil;
+import com.sk89q.worldedit.extension.platform.Actor;
+import com.sk89q.worldedit.world.gamemode.GameModes;
+import com.sk89q.worldedit.world.item.ItemType;
+import net.kyori.adventure.audience.Audience;
+import net.kyori.adventure.text.Component;
+import org.checkerframework.checker.index.qual.NonNegative;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.spongepowered.api.ResourceKey;
+import org.spongepowered.api.Server;
+import org.spongepowered.api.Sponge;
+import org.spongepowered.api.entity.living.player.Player;
+import org.spongepowered.api.entity.living.player.server.ServerPlayer;
+import org.spongepowered.api.registry.RegistryTypes;
+import org.spongepowered.api.world.server.ServerLocation;
+import org.spongepowered.math.vector.Vector3d;
+
+import java.util.UUID;
+
+import static com.sk89q.worldedit.world.gamemode.GameModes.SPECTATOR;
+
+public class SpongePlayer extends PlotPlayer {
+
+ private static boolean CHECK_EFFECTIVE = true;
+ public final ServerPlayer player;
+ private String name;
+
+ /**
+ * Please do not use this method. Instead use
+ * BukkitUtil.getPlayer(Player), as it caches player objects.
+ *
+ * @param plotAreaManager PlotAreaManager instance
+ * @param eventDispatcher EventDispatcher instance
+ * @param player Bukkit player instance
+ * @param permissionHandler PermissionHandler instance
+ */
+ public SpongePlayer(
+ final @NonNull PlotAreaManager plotAreaManager,
+ final @NonNull EventDispatcher eventDispatcher,
+ final @NonNull ServerPlayer player,
+ final @NonNull PermissionHandler permissionHandler
+ ) {
+ this(plotAreaManager, eventDispatcher, player, false, permissionHandler);
+ }
+
+ public SpongePlayer(
+ final @NonNull PlotAreaManager plotAreaManager,
+ final @NonNull EventDispatcher eventDispatcher,
+ final @NonNull ServerPlayer player,
+ final boolean realPlayer,
+ final @NonNull PermissionHandler permissionHandler
+ ) {
+ super(plotAreaManager, eventDispatcher, permissionHandler);
+ this.player = player;
+ this.setupPermissionProfile();
+ if (realPlayer) {
+ super.populatePersistentMetaMap();
+ }
+ }
+
+ @Override
+ public Actor toActor() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ServerPlayer getPlatformPlayer() {
+ return this.player;
+ }
+
+ @NonNull
+ @Override
+ public UUID getUUID() {
+/*
+TODO Fix me
+
+ if (Settings.UUID.OFFLINE) {
+ if (Settings.UUID.FORCE_LOWERCASE) {
+ return UUID.nameUUIDFromBytes(("OfflinePlayer:" +
+ getName().toLowerCase()).getBytes(Charsets.UTF_8));
+ } else {
+ return UUID.nameUUIDFromBytes(("OfflinePlayer:" +
+ getName()).getBytes(Charsets.UTF_8));
+ }
+ }
+*/
+ return player.uniqueId();
+ }
+
+ @Override
+ @NonNegative
+ public long getLastPlayed() {
+ throw new UnsupportedOperationException("TODO");
+ }
+
+ @Override
+ public boolean canTeleport(final @NonNull Location location) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ @NonNegative
+ public int hasPermissionRange(
+ final @NonNull String stub, @NonNegative final int range
+ ) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void teleport(final @NonNull Location location, final @NonNull TeleportCause cause) {
+ if (Math.abs(location.getX()) >= 30000000 || Math.abs(location.getZ()) >= 30000000) {
+ return;
+ }
+ final ServerLocation spongeLocation = ServerLocation.of(
+ ResourceKey.resolve(location.getWorldName()),
+ location.getX() + 0.5,
+ location.getY(),
+ location.getZ() + 0.5
+ );
+ //TODO has not been tested.
+ player.setLocationAndRotation(spongeLocation, Vector3d.from(location.getPitch(), location.getYaw(), 0));
+ }
+
+ @Override
+ public String getName() {
+ if (this.name == null) {
+ this.name = this.player.name();
+ }
+ return this.player.name();
+ }
+
+ @Override
+ public void setCompassTarget(Location location) {
+ //Setting compass targets changed since the last Sponge API.
+ }
+
+ @Override
+ public Location getLocationFull() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setWeather(final @NonNull PlotWeather weather) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public com.sk89q.worldedit.world.gamemode.GameMode getGameMode() {
+ return GameModes.get(player.gameMode().get().key(RegistryTypes.GAME_MODE).asString());
+ }
+
+ @Override
+ public void setGameMode(final com.sk89q.worldedit.world.gamemode.GameMode gameMode) {
+ player.gameMode().set(Sponge.game().registry(RegistryTypes.GAME_MODE).value(ResourceKey.resolve(gameMode.getId())));
+ }
+
+ @Override
+ public void setTime(final long time) {
+ throw new UnsupportedOperationException("Sponge still doesn't support this after more than 4 years of work on API 8.");
+ }
+
+ @Override
+ public boolean getFlight() {
+ return player.canFly().get();
+ }
+
+ @Override
+ public void setFlight(boolean fly) {
+ this.player.canFly().set(fly);
+ }
+
+ @Override
+ public void playMusic(final @NonNull Location location, final @NonNull ItemType id) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void kick(final String message) {
+ this.player.kick(Component.text(message));
+ }
+
+ @Override
+ public void stopSpectating() {
+ if (getGameMode() == SPECTATOR) {
+ this.player.spectatorTarget().set(null);
+ }
+ }
+
+ @Override
+ public boolean isBanned() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public @NonNull Audience getAudience() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean canSee(final PlotPlayer> other) {
+ if (other instanceof ConsolePlayer) {
+ return true;
+ } else {
+ return this.player.canSee(null); //TODO Fix Me?
+ }
+ }
+
+}
diff --git a/Sponge/src/main/java/com/plotsquared/sponge/player/SpongePlayerManager.java b/Sponge/src/main/java/com/plotsquared/sponge/player/SpongePlayerManager.java
new file mode 100644
index 000000000..ac8011685
--- /dev/null
+++ b/Sponge/src/main/java/com/plotsquared/sponge/player/SpongePlayerManager.java
@@ -0,0 +1,86 @@
+/*
+ * _____ _ _ _____ _
+ * | __ \| | | | / ____| | |
+ * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
+ * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
+ * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
+ * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
+ * | |
+ * |_|
+ * PlotSquared plot management system for Minecraft
+ * Copyright (C) 2014 - 2022 IntellectualSites
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package com.plotsquared.sponge.player;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import com.plotsquared.core.permissions.PermissionHandler;
+import com.plotsquared.core.plot.world.PlotAreaManager;
+import com.plotsquared.core.util.EventDispatcher;
+import com.plotsquared.core.util.PlayerManager;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.spongepowered.api.Server;
+import org.spongepowered.api.Sponge;
+import org.spongepowered.api.entity.living.player.server.ServerPlayer;
+import org.spongepowered.api.user.UserManager;
+
+import java.util.UUID;
+
+@Singleton
+public class SpongePlayerManager extends PlayerManager {
+
+ private final PlotAreaManager plotAreaManager;
+ private final EventDispatcher eventDispatcher;
+ private final PermissionHandler permissionHandler;
+ private final UserManager userManager;
+
+ @Inject
+ public SpongePlayerManager(
+ final @NonNull PlotAreaManager plotAreaManager,
+ final @NonNull EventDispatcher eventDispatcher,
+ final @NonNull PermissionHandler permissionHandler
+ ) {
+ this.plotAreaManager = plotAreaManager;
+ this.eventDispatcher = eventDispatcher;
+ this.permissionHandler = permissionHandler;
+ userManager = Sponge.game().server().userManager();
+ }
+
+ @NonNull
+ @Override
+ public SpongePlayer getPlayer(final @NonNull ServerPlayer object) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public @NonNull SpongePlayer createPlayer(final @NonNull UUID uuid) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Nullable
+ @Override
+ public SpongeOfflinePlayer getOfflinePlayer(final @Nullable UUID uuid) {
+ throw new UnsupportedOperationException();
+ }
+
+ @NonNull
+ @Override
+ public SpongeOfflinePlayer getOfflinePlayer(final @NonNull String username) {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/Sponge/src/main/java/com/plotsquared/sponge/util/SpongeEconHandler.java b/Sponge/src/main/java/com/plotsquared/sponge/util/SpongeEconHandler.java
new file mode 100644
index 000000000..ea115691f
--- /dev/null
+++ b/Sponge/src/main/java/com/plotsquared/sponge/util/SpongeEconHandler.java
@@ -0,0 +1,71 @@
+package com.plotsquared.sponge.util;
+
+import com.google.inject.Singleton;
+import com.plotsquared.core.player.OfflinePlotPlayer;
+import com.plotsquared.core.player.PlotPlayer;
+import com.plotsquared.core.plot.PlotArea;
+import com.plotsquared.core.util.EconHandler;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.spongepowered.api.Sponge;
+import org.spongepowered.api.service.economy.Currency;
+import org.spongepowered.api.service.economy.EconomyService;
+import org.spongepowered.api.service.economy.account.UniqueAccount;
+
+import java.util.Optional;
+
+
+@Singleton
+public class SpongeEconHandler extends EconHandler {
+
+ private final Optional economyService; //TODO maybe don't store an optional?
+
+ public SpongeEconHandler() {
+ economyService = Sponge.serviceProvider().provide(EconomyService.class);
+ }
+
+ @Override
+ public boolean init() {
+ return Sponge.serviceProvider().provide(EconomyService.class).isPresent();
+ }
+
+ @Override
+ public double getBalance(final PlotPlayer> player) {
+ if(economyService.isPresent()) {
+ final Optional account = economyService.get().findOrCreateAccount(player.getUUID());
+ return account
+ .map(uniqueAccount -> uniqueAccount.balance(economyService.get().defaultCurrency()).doubleValue())
+ .orElse(0.0);
+ }
+ return 0;
+ }
+
+ @Override
+ public void withdrawMoney(final PlotPlayer> player, final double amount) {
+
+ }
+
+ @Override
+ public void depositMoney(final PlotPlayer> player, final double amount) {
+
+ }
+
+ @Override
+ public void depositMoney(final OfflinePlotPlayer player, final double amount) {
+ }
+
+ @Override
+ public boolean isEnabled(final PlotArea plotArea) {
+ return false;
+ }
+
+ @Override
+ public @NonNull String format(final double balance) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isSupported() {
+ return Sponge.serviceProvider().provide(EconomyService.class).isPresent();
+ }
+
+}
diff --git a/Sponge/src/main/java/com/plotsquared/sponge/util/SpongeUtil.java b/Sponge/src/main/java/com/plotsquared/sponge/util/SpongeUtil.java
new file mode 100644
index 000000000..f0eb42926
--- /dev/null
+++ b/Sponge/src/main/java/com/plotsquared/sponge/util/SpongeUtil.java
@@ -0,0 +1,7 @@
+package com.plotsquared.sponge.util;
+
+import com.plotsquared.core.location.Location;
+import com.plotsquared.core.util.WorldUtil;
+
+public class SpongeUtil extends WorldUtil {
+}
diff --git a/Sponge/src/main/java/com/plotsquared/sponge/util/SpongeWorld.java b/Sponge/src/main/java/com/plotsquared/sponge/util/SpongeWorld.java
new file mode 100644
index 000000000..c453e6a4a
--- /dev/null
+++ b/Sponge/src/main/java/com/plotsquared/sponge/util/SpongeWorld.java
@@ -0,0 +1,25 @@
+package com.plotsquared.sponge.util;
+
+import com.plotsquared.core.location.World;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.spongepowered.api.world.server.ServerWorld;
+
+public class SpongeWorld implements World {
+
+ private final ServerWorld world;
+
+ private SpongeWorld(final ServerWorld world) {
+ this.world = world;
+ }
+
+ @Override
+ public @NonNull ServerWorld getPlatformWorld() {
+ return this.world;
+ }
+
+ @Override
+ public @NonNull String getName() {
+ return this.world.key().asString();
+ }
+
+}
diff --git a/Sponge/src/main/java/com/plotsquared/sponge/util/task/SpongeTaskManager.java b/Sponge/src/main/java/com/plotsquared/sponge/util/task/SpongeTaskManager.java
new file mode 100644
index 000000000..cd7537e2d
--- /dev/null
+++ b/Sponge/src/main/java/com/plotsquared/sponge/util/task/SpongeTaskManager.java
@@ -0,0 +1,69 @@
+package com.plotsquared.sponge.util.task;
+
+import com.plotsquared.core.util.task.PlotSquaredTask;
+import com.plotsquared.core.util.task.TaskManager;
+import com.plotsquared.core.util.task.TaskTime;
+import com.plotsquared.sponge.SpongePlatform;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.spongepowered.api.Sponge;
+import org.spongepowered.api.scheduler.Task;
+import org.spongepowered.api.util.Ticks;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.Future;
+
+public class SpongeTaskManager extends TaskManager {
+
+ private final SpongePlatform spongeMain;
+ private final TaskTime.TimeConverter timeConverter;
+
+ public SpongeTaskManager(SpongePlatform spongeMain, TaskTime.TimeConverter timeConverter) {
+ this.spongeMain = spongeMain;
+ this.timeConverter = timeConverter;
+ }
+
+ @Override
+ public T sync(final @NonNull Callable function, final int timeout) throws Exception {
+ return null; //TODO
+ }
+
+ @Override
+ public Future callMethodSync(final @NonNull Callable method) {
+ return null; //TODO
+ }
+
+ @Override
+ public PlotSquaredTask taskRepeat(@NonNull final Runnable runnable, @NonNull final TaskTime taskTime) {
+ return null; //TODO
+ }
+
+ @Override
+ public PlotSquaredTask taskRepeatAsync(@NonNull final Runnable runnable, @NonNull final TaskTime taskTime) {
+ //TODO input the current tick delay and interval using the Sponge Tick API.
+ Task task =
+ Task.builder().delay(Ticks.zero()).interval(Ticks.zero()).plugin(spongeMain.container).execute(runnable).build();
+ Sponge.asyncScheduler().submit(task);
+ return null;
+ }
+
+ @Override
+ public void taskAsync(@NonNull final Runnable runnable) {
+ //TODO
+ }
+
+ @Override
+ public void task(@NonNull final Runnable runnable) {
+ Task.builder().execute(runnable).plugin(spongeMain.container);
+ }
+
+ @Override
+ public void taskLater(@NonNull final Runnable runnable, @NonNull final TaskTime taskTime) {
+ //TODO
+ }
+
+ @Override
+ public void taskLaterAsync(@NonNull final Runnable runnable, @NonNull final TaskTime taskTime) {
+ //TODO
+ }
+
+}
diff --git a/Sponge/src/main/java/com/plotsquared/sponge/util/task/SpongeTimeConverter.java b/Sponge/src/main/java/com/plotsquared/sponge/util/task/SpongeTimeConverter.java
new file mode 100644
index 000000000..2032c3126
--- /dev/null
+++ b/Sponge/src/main/java/com/plotsquared/sponge/util/task/SpongeTimeConverter.java
@@ -0,0 +1,20 @@
+package com.plotsquared.sponge.util.task;
+
+import com.plotsquared.core.util.task.TaskTime;
+import org.checkerframework.checker.index.qual.NonNegative;
+import org.spongepowered.api.Sponge;
+import org.spongepowered.api.util.Ticks;
+
+public class SpongeTimeConverter implements TaskTime.TimeConverter {
+
+ @Override
+ public @NonNegative long msToTicks(@NonNegative final long ms) {
+ return 0; // TODO
+ }
+
+ @Override
+ public @NonNegative long ticksToMs(@NonNegative final long ticks) {
+ return 0; // TODO
+ }
+
+}
diff --git a/build.gradle.kts b/build.gradle.kts
index d2305ae38..3cd81b278 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -26,6 +26,7 @@ allprojects {
repositories {
mavenCentral()
+ mavenLocal()
maven {
name = "Sonatype OSS"
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 4d121e624..1b4d002e9 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -17,7 +17,7 @@ adventure-text-minimessage = "4.1.0-SNAPSHOT"
adventure-platform-bukkit = "4.0.1"
# Plugins
-worldedit = "7.2.8"
+worldedit = "7.2.9-SNAPSHOT"
fawe = "2.0.0"
vault = "1.7.1"
placeholderapi = "2.11.1"
@@ -66,6 +66,7 @@ adventurePlatformBukkit = { group = "net.kyori", name = "adventure-platform-bukk
# Plugins
worldeditCore = { group = "com.sk89q.worldedit", name = "worldedit-core", version.ref = "worldedit" }
worldeditBukkit = { group = "com.sk89q.worldedit", name = "worldedit-bukkit", version.ref = "worldedit" }
+worldeditSponge = { group = "com.sk89q.worldedit", name = "worldedit-sponge", version.ref = "worldedit" }
fastasyncworldeditBukkit = { group = "com.fastasyncworldedit", name = "FastAsyncWorldEdit-Bukkit", version.ref = "fawe" }
fastasyncworldeditCore = { group = "com.fastasyncworldedit", name = "FastAsyncWorldEdit-Core", version.ref = "fawe" }
vault = { group = "com.github.MilkBowl", name = "VaultAPI", version.ref = "vault" }
diff --git a/settings.gradle.kts b/settings.gradle.kts
index c6cbce9df..10c4930c2 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -1,9 +1,10 @@
rootProject.name = "PlotSquared"
-include("Core", "Bukkit")
+include("Core", "Bukkit", "Sponge")
project(":Core").name = "PlotSquared-Core"
project(":Bukkit").name = "PlotSquared-Bukkit"
+project(":Sponge").name = "PlotSquared-Sponge"
enableFeaturePreview("VERSION_CATALOGS")
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")