Add service system and rewrite Auto to use the service system

This commit is contained in:
Alexander Söderberg 2020-08-14 17:24:34 +02:00
parent 5b27b652e7
commit 87f0b1fc97
No known key found for this signature in database
GPG Key ID: C0207FF7EA146678
7 changed files with 224 additions and 98 deletions

View File

@ -115,6 +115,7 @@ shadowJar {
include(dependency('org.slf4j:slf4j-api'))
include(dependency('javax.inject:javax.inject:1'))
include(dependency('aopalliance:aopalliance:1.0'))
include(dependency('com.intellectualsites:Pipeline:1.4.0-SNAPSHOT'))
}
relocate('net.kyori.text', 'com.plotsquared.formatting.text')

View File

@ -23,6 +23,7 @@ dependencies {
compile group: 'aopalliance', name: 'aopalliance', version: '1.0'
// logging
implementation("org.apache.logging.log4j:log4j-slf4j-impl:2.8.1")
implementation('com.intellectualsites:Pipeline:1.4.0-SNAPSHOT')
}
sourceCompatibility = 1.8

View File

@ -28,6 +28,7 @@ package com.plotsquared.core;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
import com.intellectualsites.services.ServicePipeline;
import com.plotsquared.core.backup.BackupManager;
import com.plotsquared.core.configuration.caption.LocaleHolder;
import com.plotsquared.core.generator.GeneratorWrapper;
@ -262,4 +263,13 @@ public interface PlotPlatform<P> extends LocaleHolder {
return getInjector().getInstance(PermissionHandler.class);
}
/**
* Get the {@link ServicePipeline} implementation
*
* @return Service pipeline
*/
@Nonnull default ServicePipeline getServicePipeline() {
return getInjector().getInstance(ServicePipeline.class);
}
}

View File

@ -25,8 +25,9 @@
*/
package com.plotsquared.core.command;
import com.google.common.collect.Lists;
import com.google.common.reflect.TypeToken;
import com.google.inject.Inject;
import com.intellectualsites.services.ServicePipeline;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
@ -34,7 +35,6 @@ import com.plotsquared.core.database.DBFunc;
import com.plotsquared.core.events.PlayerAutoPlotEvent;
import com.plotsquared.core.events.PlotAutoMergeEvent;
import com.plotsquared.core.events.Result;
import com.plotsquared.core.events.TeleportCause;
import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.permissions.PermissionHandler;
import com.plotsquared.core.player.MetaDataAccess;
@ -42,9 +42,8 @@ import com.plotsquared.core.player.PlayerMetaDataKeys;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.PlotAreaType;
import com.plotsquared.core.plot.PlotId;
import com.plotsquared.core.plot.world.PlotAreaManager;
import com.plotsquared.core.services.plots.AutoService;
import com.plotsquared.core.util.EconHandler;
import com.plotsquared.core.util.EventDispatcher;
import com.plotsquared.core.util.Expression;
@ -56,8 +55,10 @@ import net.kyori.adventure.text.minimessage.Template;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@CommandDeclaration(command = "auto",
permission = "plots.auto",
@ -71,13 +72,23 @@ public class Auto extends SubCommand {
private final PlotAreaManager plotAreaManager;
private final EventDispatcher eventDispatcher;
private final EconHandler econHandler;
private final ServicePipeline servicePipeline;
@Inject public Auto(@Nonnull final PlotAreaManager plotAreaManager,
@Nonnull final EventDispatcher eventDispatcher,
@Nullable final EconHandler econHandler) {
@Nullable final EconHandler econHandler,
@Nonnull final ServicePipeline servicePipeline) {
this.plotAreaManager = plotAreaManager;
this.eventDispatcher = eventDispatcher;
this.econHandler = econHandler;
this.servicePipeline = servicePipeline;
this.servicePipeline.registerServiceType(TypeToken.of(AutoService.class), new AutoService.DefaultAutoService());
final AutoService.MultiPlotService multiPlotService = new AutoService.MultiPlotService();
this.servicePipeline.registerServiceImplementation(AutoService.class, multiPlotService,
Collections.singletonList(multiPlotService));
final AutoService.SinglePlotService singlePlotService = new AutoService.SinglePlotService();
this.servicePipeline.registerServiceImplementation(AutoService.class, singlePlotService,
Collections.singletonList(singlePlotService));
}
public static boolean checkAllowedPlots(PlotPlayer player, PlotArea plotarea,
@ -123,62 +134,32 @@ public class Auto extends SubCommand {
return true;
}
/**
* Teleport the player home, or claim a new plot
*
* @param player
* @param area
* @param start
* @param schematic
*/
public static void homeOrAuto(final PlotPlayer player, final PlotArea area, PlotId start,
final String schematic) {
Set<Plot> plots = player.getPlots();
if (!plots.isEmpty()) {
plots.iterator().next().teleportPlayer(player, TeleportCause.COMMAND, result -> {
});
} else {
autoClaimSafe(player, area, start, schematic);
}
}
/**
* Claim a new plot for a player
*
* @param player
* @param area
* @param start
* @param schematic
*/
public static void autoClaimSafe(final PlotPlayer<?> player, final PlotArea area, PlotId start,
final String schematic) {
private void claimSingle(@Nonnull final PlotPlayer<?> player, @Nonnull final Plot plot,
@Nonnull final PlotArea plotArea, @Nullable final String schematic) {
try (final MetaDataAccess<Boolean> metaDataAccess =
player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_AUTO)) {
metaDataAccess.set(true);
}
autoClaimFromDatabase(player, area, start, new RunnableVal<Plot>() {
plot.setOwnerAbs(player.getUUID());
final RunnableVal<Plot> runnableVal = new RunnableVal<Plot>() {
{
this.value = plot;
}
@Override public void run(final Plot plot) {
try {
TaskManager.getPlatformImplementation().sync(new AutoClaimFinishTask(player, plot, area, schematic,
TaskManager.getPlatformImplementation().sync(
new AutoClaimFinishTask(player, plot, plotArea, schematic,
PlotSquared.get().getEventDispatcher()));
} catch (final Exception e) {
e.printStackTrace();
}
}
});
}
};
DBFunc.createPlotSafe(plot, runnableVal, () -> claimSingle(player, plot, plotArea, schematic));
public static void autoClaimFromDatabase(final PlotPlayer player, final PlotArea area,
PlotId start, final RunnableVal<Plot> whenDone) {
final Plot plot = area.getNextFreePlot(player, start);
if (plot == null) {
whenDone.run(null);
return;
}
whenDone.value = plot;
plot.setOwnerAbs(player.getUUID());
DBFunc.createPlotSafe(plot, whenDone,
() -> autoClaimFromDatabase(player, area, plot.getId(), whenDone));
}
@Override public boolean onCommand(final PlotPlayer<?> player, String[] args) {
@ -313,34 +294,24 @@ public class Auto extends SubCommand {
);
}
}
// TODO handle type 2 (partial) the same as normal worlds!
if (size_x == 1 && size_z == 1) {
autoClaimSafe(player, plotarea, null, schematic);
return true;
} else {
if (plotarea.getType() == PlotAreaType.PARTIAL) {
final List<Plot> plots = this.servicePipeline
.pump(new AutoService.AutoQuery(player, null, size_x, size_z, plotarea))
.through(AutoService.class)
.getResult();
if (plots.isEmpty()) {
player.sendMessage(TranslatableCaption.of("errors.no_free_plots"));
return false;
} else if (plots.size() == 1) {
this.claimSingle(player, plots.get(0), plotarea, schematic);
} else {
final Iterator<Plot> plotIterator = plots.iterator();
while (plotIterator.hasNext()) {
plotIterator.next().claim(player, !plotIterator.hasNext(), null);
}
while (true) {
PlotId start = plotarea.getMeta("lastPlot", PlotId.of(0, 0)).getNextId();
PlotId end = PlotId.of(start.getX() + size_x - 1, start.getY() + size_z - 1);
if (plotarea.canClaim(player, start, end)) {
plotarea.setMeta("lastPlot", start);
for (final PlotId plotId : PlotId.PlotRangeIterator.range(start, end)) {
final Plot plot = plotarea.getPlot(plotId);
if (plot == null) {
return false;
}
plot.claim(player, plotId.equals(end), null);
}
final List<PlotId> plotIds = Lists.newArrayList((Iterable<? extends PlotId>)
PlotId.PlotRangeIterator.range(start, end));
final PlotId pos1 = plotIds.get(0);
final PlotAutoMergeEvent mergeEvent = this.eventDispatcher
.callAutoMerge(plotarea.getPlotAbs(pos1), plotIds);
final PlotAutoMergeEvent mergeEvent = this.eventDispatcher.callAutoMerge(plots.get(0),
plots.stream().map(Plot::getId).collect(Collectors.toList()));
if (!force && mergeEvent.getEventResult() == Result.DENY) {
player.sendMessage(
TranslatableCaption.of("events.event_denied"),
@ -348,14 +319,8 @@ public class Auto extends SubCommand {
);
return false;
}
if (!plotarea.mergePlots(mergeEvent.getPlots(), true)) {
return false;
}
break;
}
plotarea.setMeta("lastPlot", start);
return plotarea.mergePlots(mergeEvent.getPlots(), true);
}
return true;
}
}
}

View File

@ -26,6 +26,7 @@
package com.plotsquared.core.inject.modules;
import com.google.inject.AbstractModule;
import com.intellectualsites.services.ServicePipeline;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.file.YamlConfiguration;
import com.plotsquared.core.inject.annotations.BackgroundPipeline;
@ -44,6 +45,7 @@ public class PlotSquaredModule extends AbstractModule {
@Override protected void configure() {
final PlotSquared plotSquared = PlotSquared.get();
bind(ServicePipeline.class).toInstance(ServicePipeline.builder().build());
bind(YamlConfiguration.class).annotatedWith(WorldConfig.class).toInstance(plotSquared.getWorldConfiguration());
bind(File.class).annotatedWith(WorldFile.class).toInstance(plotSquared.getWorldsFile());
bind(File.class).annotatedWith(ConfigFile.class).toInstance(plotSquared.getConfigFile());

View File

@ -83,6 +83,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@ -908,31 +909,38 @@ public abstract class PlotArea {
}
}
public boolean canClaim(@Nullable final PlotPlayer player, @Nonnull final PlotId pos1,
@Nullable public List<Plot> canClaim(@Nullable final PlotPlayer player, @Nonnull final PlotId pos1,
@Nonnull final PlotId pos2) {
if (pos1.getX() == pos2.getX() && pos1.getY() == pos2.getY()) {
if (getOwnedPlot(pos1) != null) {
return false;
return null;
}
final Plot plot = getPlotAbs(pos1);
if (plot == null) {
return false;
return null;
}
return plot.canClaim(player);
if (plot.canClaim(player)) {
return Collections.singletonList(plot);
} else {
return null;
}
}
final List<Plot> plots = new LinkedList<>();
for (int x = pos1.getX(); x <= pos2.getX(); x++) {
for (int y = pos1.getY(); y <= pos2.getY(); y++) {
final PlotId id = PlotId.of(x, y);
final Plot plot = getPlotAbs(id);
if (plot == null) {
return false;
return null;
}
if (!plot.canClaim(player)) {
return false;
return null;
} else {
plots.add(plot);
}
}
}
return true;
return plots;
}
public boolean removePlot(@Nonnull final PlotId id) {

View File

@ -0,0 +1,139 @@
package com.plotsquared.core.services.plots;
import com.intellectualsites.services.types.Service;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.PlotAreaType;
import com.plotsquared.core.plot.PlotId;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;
public interface AutoService extends Service<AutoService.AutoQuery, List<Plot>> {
final class AutoQuery {
private final PlotPlayer<?> player;
private final PlotId startId;
private final int sizeX;
private final int sizeZ;
private final PlotArea plotArea;
/**
* Crate a new auto query
*
* @param player Player to claim for
* @param startId Plot ID to start searching from
* @param sizeX Number of plots along the X axis
* @param sizeZ Number of plots along the Z axis
* @param plotArea Plot area to search in
*/
public AutoQuery(@Nonnull final PlotPlayer<?> player, @Nullable final PlotId startId,
final int sizeX, final int sizeZ, @Nonnull final PlotArea plotArea) {
this.player = player;
this.startId = startId;
this.sizeX = sizeX;
this.sizeZ = sizeZ;
this.plotArea = plotArea;
}
/**
* Get the player that the plots are meant for
*
* @return Player
*/
@Nonnull public PlotPlayer<?> getPlayer() {
return this.player;
}
/**
* Get the plot ID to start searching from
*
* @return Start ID
*/
@Nullable public PlotId getStartId() {
return this.startId;
}
/**
* Get the number of plots along the X axis
*
* @return Number of plots along the X axis
*/
public int getSizeX() {
return this.sizeX;
}
/**
* Get the number of plots along the Z axis
*
* @return Number of plots along the Z axis
*/
public int getSizeZ() {
return this.sizeZ;
}
/**
* Get the plot area to search in
*
* @return Plot area
*/
@Nonnull public PlotArea getPlotArea() {
return this.plotArea;
}
}
final class DefaultAutoService implements AutoService {
@Override public List<Plot> handle(@Nonnull final AutoQuery autoQuery) {
return Collections.emptyList();
}
}
final class SinglePlotService implements AutoService, Predicate<AutoQuery> {
@Nullable @Override public List<Plot> handle(@Nonnull AutoQuery autoQuery) {
final Plot plot = autoQuery.getPlotArea().getNextFreePlot(autoQuery.getPlayer(), autoQuery.getStartId());
if (plot == null) {
return null;
}
return Collections.singletonList(plot);
}
@Override public boolean test(@Nonnull final AutoQuery autoQuery) {
return autoQuery.sizeX == 1 && autoQuery.sizeZ == 1;
}
}
final class MultiPlotService implements AutoService, Predicate<AutoQuery> {
@Override public List<Plot> handle(@Nonnull final AutoQuery autoQuery) {
/* TODO: Add timeout? */
while (true) {
final PlotId start = autoQuery.getPlotArea().getMeta("lastPlot", PlotId.of(0, 0)).getNextId();
final PlotId end = PlotId.of(start.getX() + autoQuery.getSizeX() - 1, start.getY() + autoQuery.getSizeZ() - 1);
final List<Plot> plots = autoQuery.getPlotArea().canClaim(autoQuery.getPlayer(), start, end);
if (plots != null && !plots.isEmpty()) {
autoQuery.getPlotArea().setMeta("lastPlot", start);
return plots;
}
}
}
@Override public boolean test(@Nonnull final AutoQuery autoQuery) {
return autoQuery.getPlotArea().getType() != PlotAreaType.PARTIAL;
}
}
}